MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:October 13 2009 8:24am
Subject:bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:3163)
View as plain text  
#At file:///home/daogangqu/mysql/bzrwork/bug46640/mysql-5.1-bugteam/ based on revid:dao-gang.qu@stripped

 3163 Dao-Gang.Qu@stripped	2009-10-13 [merge]
      auto merge

    removed:
      storage/innodb_plugin/README
      storage/innodb_plugin/handler/handler0vars.h
      storage/innodb_plugin/handler/win_delay_loader.cc
      storage/innodb_plugin/win-plugin/
      storage/innodb_plugin/win-plugin/README
      storage/innodb_plugin/win-plugin/win-plugin.diff
    added:
      mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
      mysql-test/suite/binlog/std_data/update-full-row.binlog
      mysql-test/suite/binlog/std_data/update-partial-row.binlog
      mysql-test/suite/binlog/std_data/write-full-row.binlog
      mysql-test/suite/binlog/std_data/write-partial-row.binlog
      mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
      mysql-test/suite/innodb/r/innodb-consistent.result
      mysql-test/suite/innodb/r/innodb_bug44571.result
      mysql-test/suite/innodb/t/innodb-consistent-master.opt
      mysql-test/suite/innodb/t/innodb-consistent.test
      mysql-test/suite/innodb/t/innodb_bug44571.test
      storage/innodb_plugin/mysql-test/innodb-consistent-master.opt
      storage/innodb_plugin/mysql-test/innodb-consistent.result
      storage/innodb_plugin/mysql-test/innodb-consistent.test
      storage/innodb_plugin/mysql-test/innodb_bug44369.result
      storage/innodb_plugin/mysql-test/innodb_bug44369.test
      storage/innodb_plugin/mysql-test/innodb_bug44571.result
      storage/innodb_plugin/mysql-test/innodb_bug44571.test
      storage/innodb_plugin/mysql-test/innodb_bug46000.result
      storage/innodb_plugin/mysql-test/innodb_bug46000.test
      storage/innodb_plugin/revert_gen.sh
      storage/innodb_plugin/scripts/export.sh
      storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c
    modified:
      mysql-test/collections/default.experimental
      mysql-test/suite/innodb/r/innodb-zip.result
      mysql-test/suite/innodb/t/innodb-zip.test
      mysql-test/t/innodb_bug34300.test
      sql/log_event.cc
      storage/innodb_plugin/CMakeLists.txt
      storage/innodb_plugin/ChangeLog
      storage/innodb_plugin/Makefile.am
      storage/innodb_plugin/btr/btr0btr.c
      storage/innodb_plugin/btr/btr0sea.c
      storage/innodb_plugin/buf/buf0buf.c
      storage/innodb_plugin/buf/buf0lru.c
      storage/innodb_plugin/buf/buf0rea.c
      storage/innodb_plugin/dict/dict0crea.c
      storage/innodb_plugin/dict/dict0dict.c
      storage/innodb_plugin/fil/fil0fil.c
      storage/innodb_plugin/fsp/fsp0fsp.c
      storage/innodb_plugin/handler/ha_innodb.cc
      storage/innodb_plugin/handler/handler0alter.cc
      storage/innodb_plugin/include/buf0buf.h
      storage/innodb_plugin/include/buf0buf.ic
      storage/innodb_plugin/include/buf0lru.h
      storage/innodb_plugin/include/buf0rea.h
      storage/innodb_plugin/include/buf0types.h
      storage/innodb_plugin/include/dict0crea.h
      storage/innodb_plugin/include/dict0dict.h
      storage/innodb_plugin/include/dict0mem.h
      storage/innodb_plugin/include/fsp0fsp.h
      storage/innodb_plugin/include/lock0lock.h
      storage/innodb_plugin/include/log0log.h
      storage/innodb_plugin/include/log0log.ic
      storage/innodb_plugin/include/log0recv.h
      storage/innodb_plugin/include/mtr0mtr.h
      storage/innodb_plugin/include/os0file.h
      storage/innodb_plugin/include/os0sync.h
      storage/innodb_plugin/include/page0page.h
      storage/innodb_plugin/include/page0zip.h
      storage/innodb_plugin/include/rem0cmp.h
      storage/innodb_plugin/include/rem0rec.ic
      storage/innodb_plugin/include/row0ins.h
      storage/innodb_plugin/include/row0mysql.h
      storage/innodb_plugin/include/srv0srv.h
      storage/innodb_plugin/include/trx0rec.h
      storage/innodb_plugin/include/trx0rec.ic
      storage/innodb_plugin/include/trx0roll.h
      storage/innodb_plugin/include/trx0sys.ic
      storage/innodb_plugin/include/trx0trx.h
      storage/innodb_plugin/include/univ.i
      storage/innodb_plugin/include/ut0auxconf.h
      storage/innodb_plugin/include/ut0byte.h
      storage/innodb_plugin/include/ut0byte.ic
      storage/innodb_plugin/include/ut0ut.h
      storage/innodb_plugin/lock/lock0lock.c
      storage/innodb_plugin/log/log0log.c
      storage/innodb_plugin/log/log0recv.c
      storage/innodb_plugin/mem/mem0mem.c
      storage/innodb_plugin/mtr/mtr0mtr.c
      storage/innodb_plugin/mysql-test/innodb-analyze.test
      storage/innodb_plugin/mysql-test/innodb-zip.result
      storage/innodb_plugin/mysql-test/innodb-zip.test
      storage/innodb_plugin/mysql-test/innodb_bug34300.test
      storage/innodb_plugin/mysql-test/innodb_bug36169.test
      storage/innodb_plugin/mysql-test/innodb_bug36172.test
      storage/innodb_plugin/mysql-test/innodb_file_format.result
      storage/innodb_plugin/mysql-test/innodb_file_format.test
      storage/innodb_plugin/os/os0file.c
      storage/innodb_plugin/page/page0cur.c
      storage/innodb_plugin/page/page0page.c
      storage/innodb_plugin/page/page0zip.c
      storage/innodb_plugin/plug.in
      storage/innodb_plugin/rem/rem0cmp.c
      storage/innodb_plugin/row/row0ins.c
      storage/innodb_plugin/row/row0merge.c
      storage/innodb_plugin/row/row0mysql.c
      storage/innodb_plugin/srv/srv0srv.c
      storage/innodb_plugin/srv/srv0start.c
      storage/innodb_plugin/sync/sync0rw.c
      storage/innodb_plugin/sync/sync0sync.c
      storage/innodb_plugin/thr/thr0loc.c
      storage/innodb_plugin/trx/trx0rec.c
      storage/innodb_plugin/trx/trx0roll.c
      storage/innodb_plugin/trx/trx0trx.c
      storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c
      storage/innodb_plugin/ut/ut0ut.c
=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2009-10-05 08:18:59 +0000
+++ b/mysql-test/collections/default.experimental	2009-10-13 02:26:15 +0000
@@ -1,6 +1,5 @@
 funcs_1.charset_collation_1              # depends on compile-time decisions
 main.plugin_load  @solaris               # Bug#42144
-binlog.binlog_tmp_table*                 # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
 main.ctype_gbk_binlog  @solaris          # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
 rpl.rpl_row_create_table*                # Bug#45576: rpl_row_create_table fails on PB2
 rpl_ndb.rpl_ndb_log                      # Bug#38998

=== added file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result	2009-10-09 08:54:48 +0000
@@ -0,0 +1,161 @@
+Verbose statements from : write-partial-row.binlog
+select txt from raw_binlog_rows where txt like '###%';
+txt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+###   @1=1
+###   @2=25769803786
+###   @3=''
+###   @4=0
+###   @5=0
+### INSERT INTO test.ba
+### SET
+###   @1=3
+###   @2=3
+###   @3=3
+### INSERT INTO test.ba
+### SET
+###   @1=1
+###   @2=1
+###   @3=1
+### INSERT INTO test.ba
+### SET
+###   @1=2
+###   @2=2
+###   @3=2
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @2=4
+###   @3=4
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @3=40
+### DELETE FROM test.ba
+### WHERE
+###   @1=2
+drop table raw_binlog_rows;
+Verbose statements from : write-full-row.binlog
+select txt from raw_binlog_rows where txt like '###%';
+txt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+###   @1=2
+###   @2=25769803786
+###   @3=''
+###   @4=0
+###   @5=0
+### INSERT INTO test.ba
+### SET
+###   @1=3
+###   @2=3
+###   @3=3
+### INSERT INTO test.ba
+### SET
+###   @1=1
+###   @2=1
+###   @3=1
+### INSERT INTO test.ba
+### SET
+###   @1=2
+###   @2=2
+###   @3=2
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @2=4
+###   @3=4
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @2=4
+###   @3=40
+### DELETE FROM test.ba
+### WHERE
+###   @1=2
+drop table raw_binlog_rows;
+Verbose statements from : update-partial-row.binlog
+select txt from raw_binlog_rows where txt like '###%';
+txt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+###   @1=3
+###   @2=25769803786
+###   @3=''
+###   @4=0
+###   @5=0
+### INSERT INTO test.ba
+### SET
+###   @1=3
+###   @2=3
+###   @3=3
+### INSERT INTO test.ba
+### SET
+###   @1=1
+###   @2=1
+###   @3=1
+### INSERT INTO test.ba
+### SET
+###   @1=2
+###   @2=2
+###   @3=2
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @2=4
+###   @3=4
+### UPDATE test.ba
+### WHERE
+###   @1=4
+###   @3=4
+### SET
+###   @1=4
+###   @3=40
+### DELETE FROM test.ba
+### WHERE
+###   @1=2
+drop table raw_binlog_rows;
+Verbose statements from : update-full-row.binlog
+select txt from raw_binlog_rows where txt like '###%';
+txt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+###   @1=4
+###   @2=25769803786
+###   @3=''
+###   @4=0
+###   @5=0
+### INSERT INTO test.ba
+### SET
+###   @1=3
+###   @2=3
+###   @3=3
+### INSERT INTO test.ba
+### SET
+###   @1=1
+###   @2=1
+###   @3=1
+### INSERT INTO test.ba
+### SET
+###   @1=2
+###   @2=2
+###   @3=2
+### INSERT INTO test.ba
+### SET
+###   @1=4
+###   @2=4
+###   @3=4
+### UPDATE test.ba
+### WHERE
+###   @1=4
+###   @2=4
+###   @3=4
+### SET
+###   @1=4
+###   @2=4
+###   @3=40
+### DELETE FROM test.ba
+### WHERE
+###   @1=2
+drop table raw_binlog_rows;

=== added file 'mysql-test/suite/binlog/std_data/update-full-row.binlog'
Binary files a/mysql-test/suite/binlog/std_data/update-full-row.binlog	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/binlog/std_data/update-full-row.binlog	2009-10-09 08:54:48 +0000 differ

=== added file 'mysql-test/suite/binlog/std_data/update-partial-row.binlog'
Binary files a/mysql-test/suite/binlog/std_data/update-partial-row.binlog	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/binlog/std_data/update-partial-row.binlog	2009-10-09 08:54:48 +0000 differ

=== added file 'mysql-test/suite/binlog/std_data/write-full-row.binlog'
Binary files a/mysql-test/suite/binlog/std_data/write-full-row.binlog	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/binlog/std_data/write-full-row.binlog	2009-10-09 08:54:48 +0000 differ

=== added file 'mysql-test/suite/binlog/std_data/write-partial-row.binlog'
Binary files a/mysql-test/suite/binlog/std_data/write-partial-row.binlog	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/binlog/std_data/write-partial-row.binlog	2009-10-09 08:54:48 +0000 differ

=== added file 'mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test'
--- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test	2009-10-09 08:54:48 +0000
@@ -0,0 +1,82 @@
+########################################################
+# Test mysqlbinlog command with Ndb produced Binlog
+# variants
+#
+# WHAT
+# ====
+#  This test aims to check that the mysqlbinlog --verbose
+#  command can output binlogs in 4 format variants, currently
+#  used by Ndb
+#
+#  1) Updates logged as write_row events
+#     Only primary key and updated columns included in the 
+#     event
+#  2) Updates logged as write_row_events
+#     All columns included in the event
+#  3) Updates logged as update_row events
+#     Only primary key and updated columns included in the
+#     event
+#  4) Updates logged as update_row events
+#     All columns included in the event
+#
+# Format variant (1) is the Ndb default.
+# Bug#47323 resulted in binlogs generated in format (1) 
+# being incorrectly parsed by the mysqlbinlog --verbose
+# option
+#
+# HOW
+# ===
+#  Row-based binlog files in each format have been 
+#  captured from an Ndb cluster
+#  These are output using the mysqlbinlog --verbose
+#  tool and the output is checked.
+#
+########################################################
+
+# We require binlog_format_row as we're independent of binlog format
+# and there's no point running the same test 3 times
+-- source include/have_binlog_format_row.inc
+
+--disable_query_log
+--let $binlog_file=write-partial-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+select txt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=write-full-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+select txt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=update-partial-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+select txt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=update-full-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+select txt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;

=== added file 'mysql-test/suite/innodb/r/innodb-consistent.result'
--- a/mysql-test/suite/innodb/r/innodb-consistent.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb-consistent.result	2009-10-09 13:37:47 +0000
@@ -0,0 +1,35 @@
+drop table if exists t1;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+begin;
+replace into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+begin;
+insert into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+7
+drop table t1;
+drop table t2;

=== modified file 'mysql-test/suite/innodb/r/innodb-zip.result'
--- a/mysql-test/suite/innodb/r/innodb-zip.result	2009-06-10 13:51:20 +0000
+++ b/mysql-test/suite/innodb/r/innodb-zip.result	2009-10-09 13:37:47 +0000
@@ -141,7 +141,7 @@ drop table t1;
 CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
 DROP TABLE t1;

=== added file 'mysql-test/suite/innodb/r/innodb_bug44571.result'
--- a/mysql-test/suite/innodb/r/innodb_bug44571.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug44571.result	2009-10-08 11:28:37 +0000
@@ -0,0 +1,9 @@
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ERROR 42000: Key column 'foo' doesn't exist in table
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+CREATE INDEX bug44571b ON bug44571 (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+DROP TABLE bug44571;

=== added file 'mysql-test/suite/innodb/t/innodb-consistent-master.opt'
--- a/mysql-test/suite/innodb/t/innodb-consistent-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb-consistent-master.opt	2009-10-09 13:37:47 +0000
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=2

=== added file 'mysql-test/suite/innodb/t/innodb-consistent.test'
--- a/mysql-test/suite/innodb/t/innodb-consistent.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb-consistent.test	2009-10-09 13:37:47 +0000
@@ -0,0 +1,59 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
+# a consistent read of the source table.
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+
+# REPLACE INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+replace into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+# INSERT INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+insert into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+select * from t1;
+drop table t1;
+drop table t2;
+
+connection default;
+disconnect a;
+disconnect b;

=== modified file 'mysql-test/suite/innodb/t/innodb-zip.test'
--- a/mysql-test/suite/innodb/t/innodb-zip.test	2009-06-24 17:18:58 +0000
+++ b/mysql-test/suite/innodb/t/innodb-zip.test	2009-10-09 13:37:47 +0000
@@ -106,7 +106,7 @@ drop table t1;
 --error ER_TOO_BIG_ROWSIZE
 CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
 DROP TABLE t1;

=== added file 'mysql-test/suite/innodb/t/innodb_bug44571.test'
--- a/mysql-test/suite/innodb/t/innodb_bug44571.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug44571.test	2009-10-08 11:28:37 +0000
@@ -0,0 +1,18 @@
+#
+# Bug#44571 InnoDB Plugin crashes on ADD INDEX
+# http://bugs.mysql.com/44571
+#
+-- source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+-- error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+# The following will fail, because the CHANGE foo bar was
+# not communicated to InnoDB.
+--error ER_NOT_KEYFILE
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+--error ER_NOT_KEYFILE
+CREATE INDEX bug44571b ON bug44571 (bar);
+DROP TABLE bug44571;

=== modified file 'mysql-test/t/innodb_bug34300.test'
--- a/mysql-test/t/innodb_bug34300.test	2009-01-31 16:10:43 +0000
+++ b/mysql-test/t/innodb_bug34300.test	2009-10-08 09:13:16 +0000
@@ -9,6 +9,7 @@
 -- disable_result_log
 
 # set packet size and reconnect 
+let $max_packet=`select @@global.max_allowed_packet`;
 SET @@global.max_allowed_packet=16777216;
 --connect (newconn, localhost, root,,)
 

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2009-10-13 01:53:13 +0000
+++ b/sql/log_event.cc	2009-10-13 08:24:28 +0000
@@ -1852,6 +1852,7 @@ Rows_log_event::print_verbose_one_row(IO
 {
   const uchar *value0= value;
   const uchar *null_bits= value;
+  uint null_bit_index= 0;
   char typestr[64]= "";
   
   value+= (m_width + 7) / 8;
@@ -1860,7 +1861,8 @@ Rows_log_event::print_verbose_one_row(IO
   
   for (size_t i= 0; i < td->size(); i ++)
   {
-    int is_null= (null_bits[i / 8] >> (i % 8))  & 0x01;
+    int is_null= (null_bits[null_bit_index / 8] 
+                  >> (null_bit_index % 8))  & 0x01;
 
     if (bitmap_is_set(cols_bitmap, i) == 0)
       continue;
@@ -1897,6 +1899,8 @@ Rows_log_event::print_verbose_one_row(IO
     }
     
     my_b_printf(file, "\n");
+    
+    null_bit_index++;
   }
   return value - value0;
 }

=== modified file 'storage/innodb_plugin/CMakeLists.txt'
--- a/storage/innodb_plugin/CMakeLists.txt	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/CMakeLists.txt	2009-10-13 07:11:42 +0000
@@ -18,14 +18,20 @@
 
 SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
 SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+
+# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
+# CMakeLists.txt still needs to work with previous versions of MySQL.
+IF (MYSQL_VERSION_ID GREATER "50137")
+	INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
+
 IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
 	SET(WIN64 TRUE)
 ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
 
 # Include directories under innodb_plugin
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innodb_plugin/include
-		    ${CMAKE_SOURCE_DIR}/storage/innodfb_plugin/handler)
+		    ${CMAKE_SOURCE_DIR}/storage/innodb_plugin/handler)
 
 # Include directories under mysql
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
@@ -36,10 +42,10 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
 
 # Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
 # due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
-IF(MSVC AND $(WIN64))
+IF (MSVC AND $(WIN64))
 	SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
 				    PROPERTIES COMPILE_FLAGS -Od)
-ENDIF(MSVC AND $(WIN64))
+ENDIF (MSVC AND $(WIN64))
 
 SET(INNODB_PLUGIN_SOURCES	btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
 			buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
@@ -74,5 +80,5 @@ SET(INNODB_PLUGIN_SOURCES	btr/btr0btr.c 
 			usr/usr0sess.c
 			ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
 			ut/ut0list.c ut/ut0wqueue.c)
-ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
-MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)
\ No newline at end of file
+ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
+MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)

=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/ChangeLog	2009-10-12 12:00:56 +0000
@@ -1,3 +1,149 @@
+2009-10-01	The InnoDB Team
+
+	* fsp/fsp0fsp.c, row/row0merge.c:
+	Clean up after a crash during DROP INDEX.  When InnoDB crashes
+	while dropping an index, ensure that the index will be completely
+	dropped during crash recovery.  The MySQL .frm file may still
+	contain the dropped index, but there is little that we can do
+	about it.
+
+2009-09-28	The InnoDB Team
+
+	* handler/ha_innodb.cc:
+	When a secondary index exists in the MySQL .frm file but not in
+	the InnoDB data dictionary, return an error instead of letting an
+	assertion fail in index_read.
+
+2009-09-28	The InnoDB Team
+
+	* btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
+	include/page0zip.h, page/page0cur.c, page/page0page.c,
+	page/page0zip.c:
+	Do not write to PAGE_INDEX_ID when restoring an uncompressed page
+	after a compression failure.  The field should only be written
+	when creating a B-tree page.  This fix addresses a race condition
+	in a debug assertion.
+
+2009-09-28	The InnoDB Team
+
+	* fil/fil0fil.c:
+	Try to prevent the reuse of tablespace identifiers after InnoDB
+	has crashed during table creation.  Also, refuse to start if files
+	with duplicate tablespace identifiers are encountered.
+
+2009-09-25	The InnoDB Team
+
+	* include/os0file.h, os/os0file.c:
+	Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
+	1453 (0x5AD) for InnoDB backend
+
+2009-09-19	The InnoDB Team
+
+	* handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
+	mysql-test/innodb-consistent.result,
+	mysql-test/innodb-consistent.test:
+	Fix Bug#37232 Innodb might get too many read locks for DML with
+	repeatable-read
+
+2009-09-19	The InnoDB Team
+
+	* fsp/fsp0fsp.c:
+	Fix Bug#31183 Tablespace full problems not reported in error log,
+	error message unclear
+
+2009-09-17	The InnoDB Team
+
+	* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
+	Make the test pass with zlib 1.2.3.3. Apparently, the definition
+	of compressBound() has changed between zlib versions, and the
+	maximum record size of a table with 1K compressed page size has
+	been reduced by one byte. This is an arbitrary test. In practical
+	applications, for good write performance, the compressed page size
+	should be chosen to be bigger than the absolute minimum.
+
+2009-09-16	The InnoDB Team
+
+	* handler/ha_innodb.cc:
+	Fix Bug#46256 drop table with unknown collation crashes innodb
+
+2009-09-16	The InnoDB Team
+
+	* dict/dict0dict.c, handler/ha_innodb.cc,
+	mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
+	row/row0mysql.c:
+	Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
+	names
+
+2009-09-16	The InnoDB Team
+
+	* handler/ha_innodb.cc, include/db0err.h,
+	mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
+	Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
+
+2009-09-02	The InnoDB Team
+
+	* include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
+	row/row0mysql.c:
+	Fix a regression introduced by the fix for MySQL bug#26316. We check
+	whether a transaction holds any AUTOINC locks before we acquire
+	the kernel mutex and release those locks.
+
+2009-08-27	The InnoDB Team
+
+	* dict/dict0dict.c, include/dict0dict.h,
+	mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
+	Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
+
+2009-08-27	The InnoDB Team
+
+	* row/row0merge.c:
+	Fix a bug in the merge sort that can corrupt indexes in fast index
+	creation. Add some consistency checks. Check that the number of
+	records remains constant in every merge sort pass.
+
+2009-08-27	The InnoDB Team
+
+	* buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+	include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
+	include/ut0ut.h, ut/ut0ut.c:
+	Make it possible to tune the buffer pool LRU eviction policy to be
+	more resistant against index scans. Introduce the settable global
+	variables innodb_old_blocks_pct and innodb_old_blocks_time for
+	controlling the buffer pool eviction policy. The parameter
+	innodb_old_blocks_pct (5..95) controls the desired amount of "old"
+	blocks in the LRU list. The default is 37, corresponding to the
+	old fixed ratio of 3/8. Each time a block is accessed, it will be
+	moved to the "new" blocks if its first access was at least
+	innodb_old_blocks_time milliseconds ago (default 0, meaning every
+	block). The idea is that in index scans, blocks will be accessed
+	a few times within innodb_old_blocks_time, and they will remain in
+	the "old" section of the LRU list. Thus, when innodb_old_blocks_time
+	is nonzero, blocks retrieved for one-time index scans will be more
+	likely candidates for eviction than blocks that are accessed in
+	random patterns.
+
+2009-08-26	The InnoDB Team
+
+	* handler/ha_innodb.cc, os/os0file.c:
+	Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
+	thread wakeups
+
+2009-08-20	The InnoDB Team
+
+	* lock/lock0lock.c:
+	Fix Bug#46650 Innodb assertion autoinc_lock == lock in
+	lock_table_remove_low on INSERT SELECT
+
+2009-08-13	The InnoDB Team
+
+	* handler/handler0alter.cc:
+	Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
+	(Valgrind)
+
+2009-08-11	The InnoDB Team
+
+	InnoDB Plugin 1.0.4 released
+
 2009-07-20	The InnoDB Team
 
 	* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,

=== modified file 'storage/innodb_plugin/Makefile.am'
--- a/storage/innodb_plugin/Makefile.am	2009-07-31 09:54:25 +0000
+++ b/storage/innodb_plugin/Makefile.am	2009-10-09 14:02:18 +0000
@@ -31,7 +31,6 @@ DEFS=			@DEFS@
 
 noinst_HEADERS=		\
 			handler/ha_innodb.h	\
-			handler/handler0vars.h	\
 			handler/i_s.h		\
 			include/btr0btr.h	\
 			include/btr0btr.ic	\

=== removed file 'storage/innodb_plugin/README'
--- a/storage/innodb_plugin/README	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/README	1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-This is the source of the InnoDB Plugin 1.0.4 for MySQL 5.1
-===========================================================
-
-Instructions for compiling the plugin:
---------------------------------------
-
-1. Get the latest MySQL 5.1 sources from
-   http://dev.mysql.com/downloads/mysql/5.1.html#source
-
-2. Replace the contents of the mysql-5.1.N/storage/innobase/ directory
-   with the contents of this directory.
-
-3. Optional (only necessary if you are going to run tests from the
-   mysql-test suite): cd into the innobase directory and run ./setup.sh
-
-4. Compile MySQL as usual.
-
-5. Enjoy!
-
-See the online documentation for more detailed instructions:
-http://www.innodb.com/doc/innodb_plugin-1.0/innodb-plugin-installation.html
-
-For more information about InnoDB visit
-http://www.innodb.com
-
-Please report any problems or issues with the plugin in the InnoDB Forums
-http://forums.innodb.com/ or in the MySQL Bugs database http://bugs.mysql.com
-
-Thank you for using the InnoDB plugin!

=== modified file 'storage/innodb_plugin/btr/btr0btr.c'
--- a/storage/innodb_plugin/btr/btr0btr.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/btr/btr0btr.c	2009-10-12 12:00:56 +0000
@@ -797,7 +797,7 @@ btr_create(
 		buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
 	}
 
-	/* Create a new index page on the the allocated segment page */
+	/* Create a new index page on the allocated segment page */
 	page_zip = buf_block_get_page_zip(block);
 
 	if (UNIV_LIKELY_NULL(page_zip)) {
@@ -1011,7 +1011,26 @@ btr_page_reorganize_low(
 	    (!page_zip_compress(page_zip, page, index, NULL))) {
 
 		/* Restore the old page and exit. */
-		buf_frame_copy(page, temp_page);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+		/* Check that the bytes that we skip are identical. */
+		ut_a(!memcmp(page, temp_page, PAGE_HEADER));
+		ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
+			     PAGE_HEADER + PAGE_N_RECS + temp_page,
+			     PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
+		ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
+			     UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
+			     FIL_PAGE_DATA_END));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+		memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
+		       PAGE_N_RECS - PAGE_N_DIR_SLOTS);
+		memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
+		       UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+		ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
 
 		goto func_exit;
 	}
@@ -1902,7 +1921,7 @@ func_start:
 				n_uniq, &heap);
 
 			/* If the new record is less than the existing record
-			the the split in the middle will copy the existing
+			the split in the middle will copy the existing
 			record to the new node. */
 			if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
 				split_rec = page_get_middle_rec(page);

=== modified file 'storage/innodb_plugin/btr/btr0sea.c'
--- a/storage/innodb_plugin/btr/btr0sea.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/btr/btr0sea.c	2009-10-08 11:28:37 +0000
@@ -957,7 +957,7 @@ btr_search_guess_on_hash(
 	/* Increment the page get statistics though we did not really
 	fix the page: for user info only */
 
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 
 	return(TRUE);
 

=== modified file 'storage/innodb_plugin/buf/buf0buf.c'
--- a/storage/innodb_plugin/buf/buf0buf.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/buf/buf0buf.c	2009-10-09 14:13:15 +0000
@@ -837,16 +837,35 @@ buf_chunk_not_freed(
 	block = chunk->blocks;
 
 	for (i = chunk->size; i--; block++) {
-		mutex_enter(&block->mutex);
-
-		if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
-		    && !buf_flush_ready_for_replace(&block->page)) {
+		ibool	ready;
 
+		switch (buf_block_get_state(block)) {
+		case BUF_BLOCK_ZIP_FREE:
+		case BUF_BLOCK_ZIP_PAGE:
+		case BUF_BLOCK_ZIP_DIRTY:
+			/* The uncompressed buffer pool should never
+			contain compressed block descriptors. */
+			ut_error;
+			break;
+		case BUF_BLOCK_NOT_USED:
+		case BUF_BLOCK_READY_FOR_USE:
+		case BUF_BLOCK_MEMORY:
+		case BUF_BLOCK_REMOVE_HASH:
+			/* Skip blocks that are not being used for
+			file pages. */
+			break;
+		case BUF_BLOCK_FILE_PAGE:
+			mutex_enter(&block->mutex);
+			ready = buf_flush_ready_for_replace(&block->page);
 			mutex_exit(&block->mutex);
-			return(block);
-		}
 
-		mutex_exit(&block->mutex);
+			if (!ready) {
+
+				return(block);
+			}
+
+			break;
+		}
 	}
 
 	return(NULL);
@@ -966,8 +985,6 @@ buf_pool_init(void)
 		buf_pool->no_flush[i] = os_event_create(NULL);
 	}
 
-	buf_pool->ulint_clock = 1;
-
 	/* 3. Initialize LRU fields
 	--------------------------- */
 	/* All fields are initialized by mem_zalloc(). */
@@ -1471,33 +1488,8 @@ buf_pool_resize(void)
 }
 
 /********************************************************************//**
-Moves the block to the start of the LRU list if there is a danger
-that the block would drift out of the buffer pool. */
-UNIV_INLINE
-void
-buf_block_make_young(
-/*=================*/
-	buf_page_t*	bpage)	/*!< in: block to make younger */
-{
-	ut_ad(!buf_pool_mutex_own());
-
-	/* Note that we read freed_page_clock's without holding any mutex:
-	this is allowed since the result is used only in heuristics */
-
-	if (buf_page_peek_if_too_old(bpage)) {
-
-		buf_pool_mutex_enter();
-		/* There has been freeing activity in the LRU list:
-		best to move to the head of the LRU list */
-
-		buf_LRU_make_block_young(bpage);
-		buf_pool_mutex_exit();
-	}
-}
-
-/********************************************************************//**
 Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
 the buffer pool. */
 UNIV_INTERN
 void
@@ -1515,6 +1507,36 @@ buf_page_make_young(
 }
 
 /********************************************************************//**
+Sets the time of the first access of a page and moves a page to the
+start of the buffer pool LRU list if it is too old.  This high-level
+function can be used to prevent an important page from slipping
+out of the buffer pool. */
+static
+void
+buf_page_set_accessed_make_young(
+/*=============================*/
+	buf_page_t*	bpage,		/*!< in/out: buffer block of a
+					file page */
+	unsigned	access_time)	/*!< in: bpage->access_time
+					read under mutex protection,
+					or 0 if unknown */
+{
+	ut_ad(!buf_pool_mutex_own());
+	ut_a(buf_page_in_file(bpage));
+
+	if (buf_page_peek_if_too_old(bpage)) {
+		buf_pool_mutex_enter();
+		buf_LRU_make_block_young(bpage);
+		buf_pool_mutex_exit();
+	} else if (!access_time) {
+		ulint	time_ms = ut_time_ms();
+		buf_pool_mutex_enter();
+		buf_page_set_accessed(bpage, time_ms);
+		buf_pool_mutex_exit();
+	}
+}
+
+/********************************************************************//**
 Resets the check_index_page_at_flush field of a page if found in the buffer
 pool. */
 UNIV_INTERN
@@ -1645,11 +1667,12 @@ buf_page_get_zip(
 	buf_page_t*	bpage;
 	mutex_t*	block_mutex;
 	ibool		must_read;
+	unsigned	access_time;
 
 #ifndef UNIV_LOG_DEBUG
 	ut_ad(!ibuf_inside());
 #endif
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 
 	for (;;) {
 		buf_pool_mutex_enter();
@@ -1712,14 +1735,13 @@ err_exit:
 
 got_block:
 	must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
+	access_time = buf_page_is_accessed(bpage);
 
 	buf_pool_mutex_exit();
 
-	buf_page_set_accessed(bpage, TRUE);
-
 	mutex_exit(block_mutex);
 
-	buf_block_make_young(bpage);
+	buf_page_set_accessed_make_young(bpage, access_time);
 
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	ut_a(!bpage->file_page_was_freed);
@@ -1812,7 +1834,7 @@ buf_zip_decompress(
 	switch (fil_page_get_type(frame)) {
 	case FIL_PAGE_INDEX:
 		if (page_zip_decompress(&block->page.zip,
-					block->frame)) {
+					block->frame, TRUE)) {
 			return(TRUE);
 		}
 
@@ -2000,7 +2022,7 @@ buf_page_get_gen(
 	mtr_t*		mtr)	/*!< in: mini-transaction */
 {
 	buf_block_t*	block;
-	ibool		accessed;
+	unsigned	access_time;
 	ulint		fix_type;
 	ibool		must_read;
 
@@ -2016,7 +2038,7 @@ buf_page_get_gen(
 #ifndef UNIV_LOG_DEBUG
 	ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
 #endif
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 loop:
 	block = guess;
 	buf_pool_mutex_enter();
@@ -2243,17 +2265,16 @@ wait_until_unfixed:
 	UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
 
 	buf_block_buf_fix_inc(block, file, line);
-	buf_pool_mutex_exit();
 
-	/* Check if this is the first access to the page */
+	mutex_exit(&block->mutex);
 
-	accessed = buf_page_is_accessed(&block->page);
+	/* Check if this is the first access to the page */
 
-	buf_page_set_accessed(&block->page, TRUE);
+	access_time = buf_page_is_accessed(&block->page);
 
-	mutex_exit(&block->mutex);
+	buf_pool_mutex_exit();
 
-	buf_block_make_young(&block->page);
+	buf_page_set_accessed_make_young(&block->page, access_time);
 
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	ut_a(!block->page.file_page_was_freed);
@@ -2306,7 +2327,7 @@ wait_until_unfixed:
 
 	mtr_memo_push(mtr, block, fix_type);
 
-	if (!accessed) {
+	if (!access_time) {
 		/* In the case of a first access, try to apply linear
 		read-ahead */
 
@@ -2336,7 +2357,7 @@ buf_page_optimistic_get_func(
 	ulint		line,	/*!< in: line where called */
 	mtr_t*		mtr)	/*!< in: mini-transaction */
 {
-	ibool		accessed;
+	unsigned	access_time;
 	ibool		success;
 	ulint		fix_type;
 
@@ -2353,14 +2374,16 @@ buf_page_optimistic_get_func(
 	}
 
 	buf_block_buf_fix_inc(block, file, line);
-	accessed = buf_page_is_accessed(&block->page);
-	buf_page_set_accessed(&block->page, TRUE);
 
 	mutex_exit(&block->mutex);
 
-	buf_block_make_young(&block->page);
+	/* Check if this is the first access to the page.
+	We do a dirty read on purpose, to avoid mutex contention.
+	This field is only used for heuristic purposes; it does not
+	affect correctness. */
 
-	/* Check if this is the first access to the page */
+	access_time = buf_page_is_accessed(&block->page);
+	buf_page_set_accessed_make_young(&block->page, access_time);
 
 	ut_ad(!ibuf_inside()
 	      || ibuf_page(buf_block_get_space(block),
@@ -2412,7 +2435,7 @@ buf_page_optimistic_get_func(
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	ut_a(block->page.file_page_was_freed == FALSE);
 #endif
-	if (UNIV_UNLIKELY(!accessed)) {
+	if (UNIV_UNLIKELY(!access_time)) {
 		/* In the case of a first access, try to apply linear
 		read-ahead */
 
@@ -2425,7 +2448,7 @@ buf_page_optimistic_get_func(
 	ut_a(ibuf_count_get(buf_block_get_space(block),
 			    buf_block_get_page_no(block)) == 0);
 #endif
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 
 	return(TRUE);
 }
@@ -2473,8 +2496,20 @@ buf_page_get_known_nowait(
 
 	mutex_exit(&block->mutex);
 
-	if (mode == BUF_MAKE_YOUNG) {
-		buf_block_make_young(&block->page);
+	if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
+		buf_pool_mutex_enter();
+		buf_LRU_make_block_young(&block->page);
+		buf_pool_mutex_exit();
+	} else if (!buf_page_is_accessed(&block->page)) {
+		/* Above, we do a dirty read on purpose, to avoid
+		mutex contention.  The field buf_page_t::access_time
+		is only used for heuristic purposes.  Writes to the
+		field must be protected by mutex, however. */
+		ulint	time_ms = ut_time_ms();
+
+		buf_pool_mutex_enter();
+		buf_page_set_accessed(&block->page, time_ms);
+		buf_pool_mutex_exit();
 	}
 
 	ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
@@ -2513,7 +2548,7 @@ buf_page_get_known_nowait(
 	     || (ibuf_count_get(buf_block_get_space(block),
 				buf_block_get_page_no(block)) == 0));
 #endif
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 
 	return(TRUE);
 }
@@ -2589,7 +2624,7 @@ buf_page_try_get_func(
 #endif /* UNIV_DEBUG_FILE_ACCESSES */
 	buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
 
-	buf_pool->n_page_gets++;
+	buf_pool->stat.n_page_gets++;
 
 #ifdef UNIV_IBUF_COUNT_DEBUG
 	ut_a(ibuf_count_get(buf_block_get_space(block),
@@ -2608,10 +2643,10 @@ buf_page_init_low(
 	buf_page_t*	bpage)	/*!< in: block to init */
 {
 	bpage->flush_type = BUF_FLUSH_LRU;
-	bpage->accessed = FALSE;
 	bpage->io_fix = BUF_IO_NONE;
 	bpage->buf_fix_count = 0;
 	bpage->freed_page_clock = 0;
+	bpage->access_time = 0;
 	bpage->newest_modification = 0;
 	bpage->oldest_modification = 0;
 	HASH_INVALIDATE(bpage, hash);
@@ -2907,6 +2942,7 @@ buf_page_create(
 	buf_frame_t*	frame;
 	buf_block_t*	block;
 	buf_block_t*	free_block	= NULL;
+	ulint		time_ms		= ut_time_ms();
 
 	ut_ad(mtr);
 	ut_ad(space || !zip_size);
@@ -2953,7 +2989,7 @@ buf_page_create(
 	buf_LRU_add_block(&block->page, FALSE);
 
 	buf_block_buf_fix_inc(block, __FILE__, __LINE__);
-	buf_pool->n_pages_created++;
+	buf_pool->stat.n_pages_created++;
 
 	if (zip_size) {
 		void*	data;
@@ -2990,12 +3026,12 @@ buf_page_create(
 		rw_lock_x_unlock(&block->lock);
 	}
 
+	buf_page_set_accessed(&block->page, time_ms);
+
 	buf_pool_mutex_exit();
 
 	mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
 
-	buf_page_set_accessed(&block->page, TRUE);
-
 	mutex_exit(&block->mutex);
 
 	/* Delete possible entries for the page from the insert buffer:
@@ -3201,7 +3237,7 @@ corrupt:
 
 		ut_ad(buf_pool->n_pend_reads > 0);
 		buf_pool->n_pend_reads--;
-		buf_pool->n_pages_read++;
+		buf_pool->stat.n_pages_read++;
 
 		if (uncompressed) {
 			rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
@@ -3221,7 +3257,7 @@ corrupt:
 					     BUF_IO_WRITE);
 		}
 
-		buf_pool->n_pages_written++;
+		buf_pool->stat.n_pages_written++;
 
 		break;
 
@@ -3251,7 +3287,32 @@ void
 buf_pool_invalidate(void)
 /*=====================*/
 {
-	ibool	freed;
+	ibool		freed;
+	enum buf_flush	i;
+
+	buf_pool_mutex_enter();
+
+	for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
+
+		/* As this function is called during startup and
+		during redo application phase during recovery, InnoDB
+		is single threaded (apart from IO helper threads) at
+		this stage. No new write batch can be in intialization
+		stage at this point. */
+		ut_ad(buf_pool->init_flush[i] == FALSE);
+
+		/* However, it is possible that a write batch that has
+		been posted earlier is still not complete. For buffer
+		pool invalidation to proceed we must ensure there is NO
+		write activity happening. */
+		if (buf_pool->n_flush[i] > 0) {
+			buf_pool_mutex_exit();
+			buf_flush_wait_batch_end(i);
+			buf_pool_mutex_enter();
+		}
+	}
+
+	buf_pool_mutex_exit();
 
 	ut_ad(buf_all_freed());
 
@@ -3266,6 +3327,14 @@ buf_pool_invalidate(void)
 	ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
 	ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
 
+	buf_pool->freed_page_clock = 0;
+	buf_pool->LRU_old = NULL;
+	buf_pool->LRU_old_len = 0;
+	buf_pool->LRU_flush_ended = 0;
+
+	memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
+	buf_refresh_io_stats();
+
 	buf_pool_mutex_exit();
 }
 
@@ -3528,6 +3597,7 @@ buf_print(void)
 		"n pending decompressions %lu\n"
 		"n pending reads %lu\n"
 		"n pending flush LRU %lu list %lu single page %lu\n"
+		"pages made young %lu, not young %lu\n"
 		"pages read %lu, created %lu, written %lu\n",
 		(ulong) size,
 		(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
@@ -3538,8 +3608,11 @@ buf_print(void)
 		(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
 		(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
 		(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
-		(ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
-		(ulong) buf_pool->n_pages_written);
+		(ulong) buf_pool->stat.n_pages_made_young,
+		(ulong) buf_pool->stat.n_pages_not_made_young,
+		(ulong) buf_pool->stat.n_pages_read,
+		(ulong) buf_pool->stat.n_pages_created,
+		(ulong) buf_pool->stat.n_pages_written);
 
 	/* Count the number of blocks belonging to each index in the buffer */
 
@@ -3744,10 +3817,9 @@ buf_print_io(
 {
 	time_t	current_time;
 	double	time_elapsed;
-	ulint	size;
+	ulint	n_gets_diff;
 
 	ut_ad(buf_pool);
-	size = buf_pool->curr_size;
 
 	buf_pool_mutex_enter();
 
@@ -3755,12 +3827,14 @@ buf_print_io(
 		"Buffer pool size   %lu\n"
 		"Free buffers       %lu\n"
 		"Database pages     %lu\n"
+		"Old database pages %lu\n"
 		"Modified db pages  %lu\n"
 		"Pending reads %lu\n"
 		"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
-		(ulong) size,
+		(ulong) buf_pool->curr_size,
 		(ulong) UT_LIST_GET_LEN(buf_pool->free),
 		(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
+		(ulong) buf_pool->LRU_old_len,
 		(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
 		(ulong) buf_pool->n_pend_reads,
 		(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
@@ -3772,37 +3846,66 @@ buf_print_io(
 	current_time = time(NULL);
 	time_elapsed = 0.001 + difftime(current_time,
 					buf_pool->last_printout_time);
-	buf_pool->last_printout_time = current_time;
 
 	fprintf(file,
+		"Pages made young %lu, not young %lu\n"
+		"%.2f youngs/s, %.2f non-youngs/s\n"
 		"Pages read %lu, created %lu, written %lu\n"
 		"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
-		(ulong) buf_pool->n_pages_read,
-		(ulong) buf_pool->n_pages_created,
-		(ulong) buf_pool->n_pages_written,
-		(buf_pool->n_pages_read - buf_pool->n_pages_read_old)
+		(ulong) buf_pool->stat.n_pages_made_young,
+		(ulong) buf_pool->stat.n_pages_not_made_young,
+		(buf_pool->stat.n_pages_made_young
+		 - buf_pool->old_stat.n_pages_made_young)
+		/ time_elapsed,
+		(buf_pool->stat.n_pages_not_made_young
+		 - buf_pool->old_stat.n_pages_not_made_young)
+		/ time_elapsed,
+		(ulong) buf_pool->stat.n_pages_read,
+		(ulong) buf_pool->stat.n_pages_created,
+		(ulong) buf_pool->stat.n_pages_written,
+		(buf_pool->stat.n_pages_read
+		 - buf_pool->old_stat.n_pages_read)
 		/ time_elapsed,
-		(buf_pool->n_pages_created - buf_pool->n_pages_created_old)
+		(buf_pool->stat.n_pages_created
+		 - buf_pool->old_stat.n_pages_created)
 		/ time_elapsed,
-		(buf_pool->n_pages_written - buf_pool->n_pages_written_old)
+		(buf_pool->stat.n_pages_written
+		 - buf_pool->old_stat.n_pages_written)
 		/ time_elapsed);
 
-	if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
-		fprintf(file, "Buffer pool hit rate %lu / 1000\n",
+	n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
+
+	if (n_gets_diff) {
+		fprintf(file,
+			"Buffer pool hit rate %lu / 1000,"
+			" young-making rate %lu / 1000 not %lu / 1000\n",
+			(ulong)
+			(1000 - ((1000 * (buf_pool->stat.n_pages_read
+					  - buf_pool->old_stat.n_pages_read))
+				 / (buf_pool->stat.n_page_gets
+				    - buf_pool->old_stat.n_page_gets))),
+			(ulong)
+			(1000 * (buf_pool->stat.n_pages_made_young
+				 - buf_pool->old_stat.n_pages_made_young)
+			 / n_gets_diff),
 			(ulong)
-			(1000 - ((1000 * (buf_pool->n_pages_read
-					  - buf_pool->n_pages_read_old))
-				 / (buf_pool->n_page_gets
-				    - buf_pool->n_page_gets_old))));
+			(1000 * (buf_pool->stat.n_pages_not_made_young
+				 - buf_pool->old_stat.n_pages_not_made_young)
+			 / n_gets_diff));
 	} else {
 		fputs("No buffer pool page gets since the last printout\n",
 		      file);
 	}
 
-	buf_pool->n_page_gets_old = buf_pool->n_page_gets;
-	buf_pool->n_pages_read_old = buf_pool->n_pages_read;
-	buf_pool->n_pages_created_old = buf_pool->n_pages_created;
-	buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+	/* Statistics about read ahead algorithm */
+	fprintf(file, "Pages read ahead %.2f/s,"
+		" evicted without access %.2f/s\n",
+		(buf_pool->stat.n_ra_pages_read
+		- buf_pool->old_stat.n_ra_pages_read)
+		/ time_elapsed,
+		(buf_pool->stat.n_ra_pages_evicted
+		- buf_pool->old_stat.n_ra_pages_evicted)
+		/ time_elapsed);
 
 	/* Print some values to help us with visualizing what is
 	happening with LRU eviction. */
@@ -3814,6 +3917,7 @@ buf_print_io(
 		buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
 		buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
 
+	buf_refresh_io_stats();
 	buf_pool_mutex_exit();
 }
 
@@ -3825,10 +3929,7 @@ buf_refresh_io_stats(void)
 /*======================*/
 {
 	buf_pool->last_printout_time = time(NULL);
-	buf_pool->n_page_gets_old = buf_pool->n_page_gets;
-	buf_pool->n_pages_read_old = buf_pool->n_pages_read;
-	buf_pool->n_pages_created_old = buf_pool->n_pages_created;
-	buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+	buf_pool->old_stat = buf_pool->stat;
 }
 
 /*********************************************************************//**

=== modified file 'storage/innodb_plugin/buf/buf0lru.c'
--- a/storage/innodb_plugin/buf/buf0lru.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/buf/buf0lru.c	2009-10-12 12:00:56 +0000
@@ -49,18 +49,22 @@ Created 11/5/1995 Heikki Tuuri
 #include "log0recv.h"
 #include "srv0srv.h"
 
-/** The number of blocks from the LRU_old pointer onward, including the block
-pointed to, must be 3/8 of the whole LRU list length, except that the
-tolerance defined below is allowed. Note that the tolerance must be small
-enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
-LRU_old pointer is not allowed to point to either end of the LRU list. */
+/** The number of blocks from the LRU_old pointer onward, including
+the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+of the whole LRU list length, except that the tolerance defined below
+is allowed. Note that the tolerance must be small enough such that for
+even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
+allowed to point to either end of the LRU list. */
 
 #define BUF_LRU_OLD_TOLERANCE	20
 
-/** The whole LRU list length is divided by this number to determine an
-initial segment in buf_LRU_get_recent_limit */
-
-#define BUF_LRU_INITIAL_RATIO	8
+/** The minimum amount of non-old blocks when the LRU_old list exists
+(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
+@see buf_LRU_old_adjust_len */
+#define BUF_LRU_NON_OLD_MIN_LEN	5
+#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
+# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
+#endif
 
 /** When dropping the search hash index entries before deleting an ibd
 file, we build a local array of pages belonging to that tablespace
@@ -107,6 +111,15 @@ UNIV_INTERN buf_LRU_stat_t	buf_LRU_stat_
 
 /* @} */
 
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks.  Protected by buf_pool_mutex. */
+UNIV_INTERN uint	buf_LRU_old_ratio;
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago.  Not protected by any mutex or latch. */
+UNIV_INTERN uint	buf_LRU_old_threshold_ms;
+/* @} */
+
 /******************************************************************//**
 Takes a block out of the LRU list and page hash table.
 If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
@@ -428,42 +441,6 @@ next_page:
 	}
 }
 
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return	the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void)
-/*==========================*/
-{
-	const buf_page_t*	bpage;
-	ulint			len;
-	ulint			limit;
-
-	buf_pool_mutex_enter();
-
-	len = UT_LIST_GET_LEN(buf_pool->LRU);
-
-	if (len < BUF_LRU_OLD_MIN_LEN) {
-		/* The LRU list is too short to do read-ahead */
-
-		buf_pool_mutex_exit();
-
-		return(0);
-	}
-
-	bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
-	limit = buf_page_get_LRU_position(bpage);
-	len /= BUF_LRU_INITIAL_RATIO;
-
-	buf_pool_mutex_exit();
-
-	return(limit > len ? (limit - len) : 0);
-}
-
 /********************************************************************//**
 Insert a compressed block into buf_pool->zip_clean in the LRU order. */
 UNIV_INTERN
@@ -594,6 +571,7 @@ buf_LRU_free_from_common_LRU_list(
 	     bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
 
 		enum buf_lru_free_block_status	freed;
+		unsigned			accessed;
 		mutex_t*			block_mutex
 			= buf_page_get_mutex(bpage);
 
@@ -601,11 +579,18 @@ buf_LRU_free_from_common_LRU_list(
 		ut_ad(bpage->in_LRU_list);
 
 		mutex_enter(block_mutex);
+		accessed = buf_page_is_accessed(bpage);
 		freed = buf_LRU_free_block(bpage, TRUE, NULL);
 		mutex_exit(block_mutex);
 
 		switch (freed) {
 		case BUF_LRU_FREED:
+			/* Keep track of pages that are evicted without
+			ever being accessed. This gives us a measure of
+			the effectiveness of readahead */
+			if (!accessed) {
+				++buf_pool->stat.n_ra_pages_evicted;
+			}
 			return(TRUE);
 
 		case BUF_LRU_NOT_FREED:
@@ -953,8 +938,10 @@ buf_LRU_old_adjust_len(void)
 
 	ut_a(buf_pool->LRU_old);
 	ut_ad(buf_pool_mutex_own());
-#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
-# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
+	ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
+	ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
+#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
+# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
 #endif
 #ifdef UNIV_LRU_DEBUG
 	/* buf_pool->LRU_old must be the first item in the LRU list
@@ -966,34 +953,39 @@ buf_LRU_old_adjust_len(void)
 	     || UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
 #endif /* UNIV_LRU_DEBUG */
 
+	old_len = buf_pool->LRU_old_len;
+	new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+			 * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+			 UT_LIST_GET_LEN(buf_pool->LRU)
+			 - (BUF_LRU_OLD_TOLERANCE
+			    + BUF_LRU_NON_OLD_MIN_LEN));
+
 	for (;;) {
-		old_len = buf_pool->LRU_old_len;
-		new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+		buf_page_t*	LRU_old = buf_pool->LRU_old;
 
-		ut_ad(buf_pool->LRU_old->in_LRU_list);
-		ut_a(buf_pool->LRU_old);
+		ut_a(LRU_old);
+		ut_ad(LRU_old->in_LRU_list);
 #ifdef UNIV_LRU_DEBUG
-		ut_a(buf_pool->LRU_old->old);
+		ut_a(LRU_old->old);
 #endif /* UNIV_LRU_DEBUG */
 
 		/* Update the LRU_old pointer if necessary */
 
-		if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
+		if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
 
-			buf_pool->LRU_old = UT_LIST_GET_PREV(
-				LRU, buf_pool->LRU_old);
+			buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
+				LRU, LRU_old);
 #ifdef UNIV_LRU_DEBUG
-			ut_a(!buf_pool->LRU_old->old);
+			ut_a(!LRU_old->old);
 #endif /* UNIV_LRU_DEBUG */
-			buf_page_set_old(buf_pool->LRU_old, TRUE);
-			buf_pool->LRU_old_len++;
+			buf_page_set_old(LRU_old, TRUE);
+			old_len = ++buf_pool->LRU_old_len;
 
 		} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
 
-			buf_page_set_old(buf_pool->LRU_old, FALSE);
-			buf_pool->LRU_old = UT_LIST_GET_NEXT(
-				LRU, buf_pool->LRU_old);
-			buf_pool->LRU_old_len--;
+			buf_page_set_old(LRU_old, FALSE);
+			buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
+			old_len = --buf_pool->LRU_old_len;
 		} else {
 			return;
 		}
@@ -1021,6 +1013,7 @@ buf_LRU_old_init(void)
 
 	while (bpage != NULL) {
 		ut_ad(bpage->in_LRU_list);
+		ut_ad(buf_page_in_file(bpage));
 		buf_page_set_old(bpage, TRUE);
 		bpage = UT_LIST_GET_NEXT(LRU, bpage);
 	}
@@ -1075,16 +1068,19 @@ buf_LRU_remove_block(
 
 	if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
 
-		/* Below: the previous block is guaranteed to exist, because
-		the LRU_old pointer is only allowed to differ by the
-		tolerance value from strict 3/8 of the LRU list length. */
+		/* Below: the previous block is guaranteed to exist,
+		because the LRU_old pointer is only allowed to differ
+		by BUF_LRU_OLD_TOLERANCE from strict
+		buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
+		list length. */
+		buf_page_t*	prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
 
-		buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
-		ut_a(buf_pool->LRU_old);
+		ut_a(prev_bpage);
 #ifdef UNIV_LRU_DEBUG
-		ut_a(!buf_pool->LRU_old->old);
+		ut_a(!prev_bpage->old);
 #endif /* UNIV_LRU_DEBUG */
-		buf_page_set_old(buf_pool->LRU_old, TRUE);
+		buf_pool->LRU_old = prev_bpage;
+		buf_page_set_old(prev_bpage, TRUE);
 
 		buf_pool->LRU_old_len++;
 	}
@@ -1149,39 +1145,25 @@ buf_LRU_add_block_to_end_low(
 /*=========================*/
 	buf_page_t*	bpage)	/*!< in: control block */
 {
-	buf_page_t*	last_bpage;
-
 	ut_ad(buf_pool);
 	ut_ad(bpage);
 	ut_ad(buf_pool_mutex_own());
 
 	ut_a(buf_page_in_file(bpage));
 
-	last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-
-	if (last_bpage) {
-		bpage->LRU_position = last_bpage->LRU_position;
-	} else {
-		bpage->LRU_position = buf_pool_clock_tic();
-	}
-
 	ut_ad(!bpage->in_LRU_list);
 	UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
 	ut_d(bpage->in_LRU_list = TRUE);
 
 	buf_page_set_old(bpage, TRUE);
 
-	if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-
-		buf_pool->LRU_old_len++;
-	}
-
 	if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
 
 		ut_ad(buf_pool->LRU_old);
 
 		/* Adjust the length of the old block list if necessary */
 
+		buf_pool->LRU_old_len++;
 		buf_LRU_old_adjust_len();
 
 	} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1189,6 +1171,7 @@ buf_LRU_add_block_to_end_low(
 		/* The LRU list is now long enough for LRU_old to become
 		defined: init it */
 
+		buf_pool->LRU_old_len++;
 		buf_LRU_old_init();
 	}
 
@@ -1222,7 +1205,6 @@ buf_LRU_add_block_low(
 
 		UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
 
-		bpage->LRU_position = buf_pool_clock_tic();
 		bpage->freed_page_clock = buf_pool->freed_page_clock;
 	} else {
 #ifdef UNIV_LRU_DEBUG
@@ -1237,11 +1219,6 @@ buf_LRU_add_block_low(
 		UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
 				     bpage);
 		buf_pool->LRU_old_len++;
-
-		/* We copy the LRU position field of the previous block
-		to the new block */
-
-		bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
 	}
 
 	ut_d(bpage->in_LRU_list = TRUE);
@@ -1295,6 +1272,12 @@ buf_LRU_make_block_young(
 /*=====================*/
 	buf_page_t*	bpage)	/*!< in: control block */
 {
+	ut_ad(buf_pool_mutex_own());
+
+	if (bpage->old) {
+		buf_pool->stat.n_pages_made_young++;
+	}
+
 	buf_LRU_remove_block(bpage);
 	buf_LRU_add_block_low(bpage, FALSE);
 }
@@ -1847,6 +1830,50 @@ buf_LRU_block_free_hashed_page(
 	buf_LRU_block_free_non_file_page(block);
 }
 
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return	updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+	uint	old_pct,/*!< in: Reserve this percentage of
+			the buffer pool for "old" blocks. */
+	ibool	adjust)	/*!< in: TRUE=adjust the LRU list;
+			FALSE=just assign buf_LRU_old_ratio
+			during the initialization of InnoDB */
+{
+	uint	ratio;
+
+	ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
+	if (ratio < BUF_LRU_OLD_RATIO_MIN) {
+		ratio = BUF_LRU_OLD_RATIO_MIN;
+	} else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
+		ratio = BUF_LRU_OLD_RATIO_MAX;
+	}
+
+	if (adjust) {
+		buf_pool_mutex_enter();
+
+		if (ratio != buf_LRU_old_ratio) {
+			buf_LRU_old_ratio = ratio;
+
+			if (UT_LIST_GET_LEN(buf_pool->LRU)
+			    >= BUF_LRU_OLD_MIN_LEN) {
+				buf_LRU_old_adjust_len();
+			}
+		}
+
+		buf_pool_mutex_exit();
+	} else {
+		buf_LRU_old_ratio = ratio;
+	}
+
+	/* the reverse of 
+	ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
+	return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
+}
+
 /********************************************************************//**
 Update the historical stats that we are collecting for LRU eviction
 policy at the end of each interval. */
@@ -1896,7 +1923,6 @@ buf_LRU_validate(void)
 	buf_block_t*	block;
 	ulint		old_len;
 	ulint		new_len;
-	ulint		LRU_pos;
 
 	ut_ad(buf_pool);
 	buf_pool_mutex_enter();
@@ -1905,7 +1931,11 @@ buf_LRU_validate(void)
 
 		ut_a(buf_pool->LRU_old);
 		old_len = buf_pool->LRU_old_len;
-		new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+		new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+				 * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+				 UT_LIST_GET_LEN(buf_pool->LRU)
+				 - (BUF_LRU_OLD_TOLERANCE
+				    + BUF_LRU_NON_OLD_MIN_LEN));
 		ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
 		ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
 	}
@@ -1943,16 +1973,7 @@ buf_LRU_validate(void)
 			ut_a(buf_pool->LRU_old == bpage);
 		}
 
-		LRU_pos	= buf_page_get_LRU_position(bpage);
-
 		bpage = UT_LIST_GET_NEXT(LRU, bpage);
-
-		if (bpage) {
-			/* If the following assert fails, it may
-			not be an error: just the buf_pool clock
-			has wrapped around */
-			ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
-		}
 	}
 
 	if (buf_pool->LRU_old) {
@@ -2000,9 +2021,6 @@ buf_LRU_print(void)
 	ut_ad(buf_pool);
 	buf_pool_mutex_enter();
 
-	fprintf(stderr, "Pool ulint clock %lu\n",
-		(ulong) buf_pool->ulint_clock);
-
 	bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
 
 	while (bpage != NULL) {
@@ -2033,18 +2051,16 @@ buf_LRU_print(void)
 			const byte*	frame;
 		case BUF_BLOCK_FILE_PAGE:
 			frame = buf_block_get_frame((buf_block_t*) bpage);
-			fprintf(stderr, "\nLRU pos %lu type %lu"
+			fprintf(stderr, "\ntype %lu"
 				" index id %lu\n",
-				(ulong) buf_page_get_LRU_position(bpage),
 				(ulong) fil_page_get_type(frame),
 				(ulong) ut_dulint_get_low(
 					btr_page_get_index_id(frame)));
 			break;
 		case BUF_BLOCK_ZIP_PAGE:
 			frame = bpage->zip.data;
-			fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
+			fprintf(stderr, "\ntype %lu size %lu"
 				" index id %lu\n",
-				(ulong) buf_page_get_LRU_position(bpage),
 				(ulong) fil_page_get_type(frame),
 				(ulong) buf_page_get_zip_size(bpage),
 				(ulong) ut_dulint_get_low(
@@ -2052,8 +2068,7 @@ buf_LRU_print(void)
 			break;
 
 		default:
-			fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
-				(ulong) buf_page_get_LRU_position(bpage),
+			fprintf(stderr, "\n!state %lu!\n",
 				(ulong) buf_page_get_state(bpage));
 			break;
 		}

=== modified file 'storage/innodb_plugin/buf/buf0rea.c'
--- a/storage/innodb_plugin/buf/buf0rea.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/buf/buf0rea.c	2009-10-08 11:28:37 +0000
@@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
 #include "srv0start.h"
 #include "srv0srv.h"
 
-/** The size in blocks of the area where the random read-ahead algorithm counts
-the accessed pages when deciding whether to read-ahead */
-#define	BUF_READ_AHEAD_RANDOM_AREA	BUF_READ_AHEAD_AREA
-
-/** There must be at least this many pages in buf_pool in the area to start
-a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD	(1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
-
 /** The linear read-ahead area size */
 #define	BUF_READ_AHEAD_LINEAR_AREA	BUF_READ_AHEAD_AREA
 
@@ -62,7 +54,8 @@ flag is cleared and the x-lock released 
 @return 1 if a read request was queued, 0 if the page already resided
 in buf_pool, or if the page is in the doublewrite buffer blocks in
 which case it is never read into the pool, or if the tablespace does
-not exist or is being dropped */
+not exist or is being dropped 
+@return 1 if read request is issued. 0 if it is not */
 static
 ulint
 buf_read_page_low(
@@ -165,174 +158,13 @@ buf_read_page_low(
 }
 
 /********************************************************************//**
-Applies a random read-ahead in buf_pool if there are at least a threshold
-value of accessed pages from the random read-ahead area. Does not read any
-page, not even the one at the position (space, offset), if the read-ahead
-mechanism is not activated. NOTE 1: the calling thread may own latches on
-pages: to avoid deadlocks this function must be written such that it cannot
-end up waiting for these latches! NOTE 2: the calling thread must want
-access to the page given: this rule is set to prevent unintended read-aheads
-performed by ibuf routines, a situation which could result in a deadlock if
-the OS does not support asynchronous i/o.
-@return number of page read requests issued; NOTE that if we read ibuf
-pages, it may happen that the page at the given page number does not
-get read even if we return a positive value! */
-static
-ulint
-buf_read_ahead_random(
-/*==================*/
-	ulint	space,	/*!< in: space id */
-	ulint	zip_size,/*!< in: compressed page size in bytes, or 0 */
-	ulint	offset)	/*!< in: page number of a page which the current thread
-			wants to access */
-{
-	ib_int64_t	tablespace_version;
-	ulint		recent_blocks	= 0;
-	ulint		count;
-	ulint		LRU_recent_limit;
-	ulint		ibuf_mode;
-	ulint		low, high;
-	ulint		err;
-	ulint		i;
-	ulint		buf_read_ahead_random_area;
-
-	/* We have currently disabled random readahead */
-	return(0);
-
-	if (srv_startup_is_before_trx_rollback_phase) {
-		/* No read-ahead to avoid thread deadlocks */
-		return(0);
-	}
-
-	if (ibuf_bitmap_page(zip_size, offset)
-	    || trx_sys_hdr_page(space, offset)) {
-
-		/* If it is an ibuf bitmap page or trx sys hdr, we do
-		no read-ahead, as that could break the ibuf page access
-		order */
-
-		return(0);
-	}
-
-	/* Remember the tablespace version before we ask te tablespace size
-	below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
-	do not try to read outside the bounds of the tablespace! */
-
-	tablespace_version = fil_space_get_version(space);
-
-	buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
-
-	low  = (offset / buf_read_ahead_random_area)
-		* buf_read_ahead_random_area;
-	high = (offset / buf_read_ahead_random_area + 1)
-		* buf_read_ahead_random_area;
-	if (high > fil_space_get_size(space)) {
-
-		high = fil_space_get_size(space);
-	}
-
-	/* Get the minimum LRU_position field value for an initial segment
-	of the LRU list, to determine which blocks have recently been added
-	to the start of the list. */
-
-	LRU_recent_limit = buf_LRU_get_recent_limit();
-
-	buf_pool_mutex_enter();
-
-	if (buf_pool->n_pend_reads
-	    > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
-		buf_pool_mutex_exit();
-
-		return(0);
-	}
-
-	/* Count how many blocks in the area have been recently accessed,
-	that is, reside near the start of the LRU list. */
-
-	for (i = low; i < high; i++) {
-		const buf_page_t*	bpage = buf_page_hash_get(space, i);
-
-		if (bpage
-		    && buf_page_is_accessed(bpage)
-		    && (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
-
-			recent_blocks++;
-
-			if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-
-				buf_pool_mutex_exit();
-				goto read_ahead;
-			}
-		}
-	}
-
-	buf_pool_mutex_exit();
-	/* Do nothing */
-	return(0);
-
-read_ahead:
-	/* Read all the suitable blocks within the area */
-
-	if (ibuf_inside()) {
-		ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
-	} else {
-		ibuf_mode = BUF_READ_ANY_PAGE;
-	}
-
-	count = 0;
-
-	for (i = low; i < high; i++) {
-		/* It is only sensible to do read-ahead in the non-sync aio
-		mode: hence FALSE as the first parameter */
-
-		if (!ibuf_bitmap_page(zip_size, i)) {
-			count += buf_read_page_low(
-				&err, FALSE,
-				ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
-				space, zip_size, FALSE,
-				tablespace_version, i);
-			if (err == DB_TABLESPACE_DELETED) {
-				ut_print_timestamp(stderr);
-				fprintf(stderr,
-					"  InnoDB: Warning: in random"
-					" readahead trying to access\n"
-					"InnoDB: tablespace %lu page %lu,\n"
-					"InnoDB: but the tablespace does not"
-					" exist or is just being dropped.\n",
-					(ulong) space, (ulong) i);
-			}
-		}
-	}
-
-	/* In simulated aio we wake the aio handler threads only after
-	queuing all aio requests, in native aio the following call does
-	nothing: */
-
-	os_aio_simulated_wake_handler_threads();
-
-#ifdef UNIV_DEBUG
-	if (buf_debug_prints && (count > 0)) {
-		fprintf(stderr,
-			"Random read-ahead space %lu offset %lu pages %lu\n",
-			(ulong) space, (ulong) offset,
-			(ulong) count);
-	}
-#endif /* UNIV_DEBUG */
-
-	++srv_read_ahead_rnd;
-	return(count);
-}
-
-/********************************************************************//**
 High-level function which reads a page asynchronously from a file to the
 buffer buf_pool if it is not already there. Sets the io_fix flag and sets
 an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
 UNIV_INTERN
-ulint
+ibool
 buf_read_page(
 /*==========*/
 	ulint	space,	/*!< in: space id */
@@ -341,20 +173,17 @@ buf_read_page(
 {
 	ib_int64_t	tablespace_version;
 	ulint		count;
-	ulint		count2;
 	ulint		err;
 
 	tablespace_version = fil_space_get_version(space);
 
-	count = buf_read_ahead_random(space, zip_size, offset);
-
 	/* We do the i/o in the synchronous aio mode to save thread
 	switches: hence TRUE */
 
-	count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
-				   zip_size, FALSE,
-				   tablespace_version, offset);
-	srv_buf_pool_reads+= count2;
+	count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+				  zip_size, FALSE,
+				  tablespace_version, offset);
+	srv_buf_pool_reads += count;
 	if (err == DB_TABLESPACE_DELETED) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
@@ -371,14 +200,14 @@ buf_read_page(
 	/* Increment number of I/O operations used for LRU policy. */
 	buf_LRU_stat_inc_io();
 
-	return(count + count2);
+	return(count > 0);
 }
 
 /********************************************************************//**
 Applies linear read-ahead if in the buf_pool the page is a border page of
 a linear read-ahead area and all the pages in the area have been accessed.
 Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
 predecessor of the page, which on the leaf level of a B-tree are the next
 and previous page in the chain of leaves. To know these, the page specified
 in (space, offset) must already be present in the buf_pool. Thus, the
@@ -498,9 +327,17 @@ buf_read_ahead_linear(
 			fail_count++;
 
 		} else if (pred_bpage) {
-			int res = (ut_ulint_cmp(
-				       buf_page_get_LRU_position(bpage),
-				       buf_page_get_LRU_position(pred_bpage)));
+			/* Note that buf_page_is_accessed() returns
+			the time of the first access.  If some blocks
+			of the extent existed in the buffer pool at
+			the time of a linear access pattern, the first
+			access times may be nonmonotonic, even though
+			the latest access times were linear.  The
+			threshold (srv_read_ahead_factor) should help
+			a little against this. */
+			int res = ut_ulint_cmp(
+				buf_page_is_accessed(bpage),
+				buf_page_is_accessed(pred_bpage));
 			/* Accesses not in the right order */
 			if (res != 0 && res != asc_or_desc) {
 				fail_count++;
@@ -643,7 +480,7 @@ buf_read_ahead_linear(
 	LRU policy decision. */
 	buf_LRU_stat_inc_io();
 
-	++srv_read_ahead_seq;
+	buf_pool->stat.n_ra_pages_read += count;
 	return(count);
 }
 

=== modified file 'storage/innodb_plugin/dict/dict0crea.c'
--- a/storage/innodb_plugin/dict/dict0crea.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/dict/dict0crea.c	2009-10-08 09:13:16 +0000
@@ -1379,7 +1379,7 @@ dict_create_add_foreign_field_to_diction
 Add a single foreign key definition to the data dictionary tables in the
 database. We also generate names to constraints that were not named by the
 user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
 are given locally for this table, that is, the number is not global, as in
 the old format constraints < 4.0.18 it used to be.
 @return	error code or DB_SUCCESS */

=== modified file 'storage/innodb_plugin/dict/dict0dict.c'
--- a/storage/innodb_plugin/dict/dict0dict.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/dict/dict0dict.c	2009-10-09 12:52:18 +0000
@@ -82,9 +82,10 @@ static char	dict_ibfk[] = "_ibfk_";
 
 /*******************************************************************//**
 Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
 static
-void
+ibool
 dict_index_find_cols(
 /*=================*/
 	dict_table_t*	table,	/*!< in: table */
@@ -1169,7 +1170,7 @@ dict_col_name_is_reserved(
 	ulint			i;
 
 	for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
-		if (strcmp(name, reserved_names[i]) == 0) {
+		if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
 
 			return(TRUE);
 		}
@@ -1431,7 +1432,7 @@ add_field_size:
 
 /**********************************************************************//**
 Adds an index to the dictionary cache.
-@return	DB_SUCCESS or DB_TOO_BIG_RECORD */
+@return	DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
 UNIV_INTERN
 ulint
 dict_index_add_to_cache(
@@ -1457,7 +1458,10 @@ dict_index_add_to_cache(
 	ut_a(!dict_index_is_clust(index)
 	     || UT_LIST_GET_LEN(table->indexes) == 0);
 
-	dict_index_find_cols(table, index);
+	if (!dict_index_find_cols(table, index)) {
+
+		return(DB_CORRUPTION);
+	}
 
 	/* Build the cache internal representation of the index,
 	containing also the added system fields */
@@ -1665,9 +1669,10 @@ dict_index_remove_from_cache(
 
 /*******************************************************************//**
 Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
 static
-void
+ibool
 dict_index_find_cols(
 /*=================*/
 	dict_table_t*	table,	/*!< in: table */
@@ -1692,17 +1697,21 @@ dict_index_find_cols(
 			}
 		}
 
+#ifdef UNIV_DEBUG
 		/* It is an error not to find a matching column. */
 		fputs("InnoDB: Error: no matching column for ", stderr);
 		ut_print_name(stderr, NULL, FALSE, field->name);
 		fputs(" in ", stderr);
 		dict_index_name_print(stderr, NULL, index);
 		fputs("!\n", stderr);
-		ut_error;
+#endif /* UNIV_DEBUG */
+		return(FALSE);
 
 found:
 		;
 	}
+
+	return(TRUE);
 }
 #endif /* !UNIV_HOTBACKUP */
 

=== modified file 'storage/innodb_plugin/fil/fil0fil.c'
--- a/storage/innodb_plugin/fil/fil0fil.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/fil/fil0fil.c	2009-10-09 14:02:18 +0000
@@ -594,6 +594,11 @@ fil_node_create(
 
 	UT_LIST_ADD_LAST(chain, space->chain, node);
 
+	if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
+
+		fil_system->max_assigned_id = id;
+	}
+
 	mutex_exit(&fil_system->mutex);
 }
 
@@ -613,12 +618,10 @@ fil_node_open_file(
 	ulint		size_high;
 	ibool		ret;
 	ibool		success;
-#ifndef UNIV_HOTBACKUP
 	byte*		buf2;
 	byte*		page;
 	ulint		space_id;
 	ulint		flags;
-#endif /* !UNIV_HOTBACKUP */
 
 	ut_ad(mutex_own(&(system->mutex)));
 	ut_a(node->n_pending == 0);
@@ -654,9 +657,11 @@ fil_node_open_file(
 		size_bytes = (((ib_int64_t)size_high) << 32)
 			+ (ib_int64_t)size_low;
 #ifdef UNIV_HOTBACKUP
-		node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
-		/* TODO: adjust to zip_size, like below? */
-#else
+		if (space->id == 0) {
+			node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+			goto add_size;
+		}
+#endif /* UNIV_HOTBACKUP */
 		ut_a(space->purpose != FIL_LOG);
 		ut_a(space->id != 0);
 
@@ -735,7 +740,10 @@ fil_node_open_file(
 				(size_bytes
 				 / dict_table_flags_to_zip_size(flags));
 		}
-#endif
+
+#ifdef UNIV_HOTBACKUP
+add_size:
+#endif /* UNIV_HOTBACKUP */
 		space->size += node->size;
 	}
 
@@ -955,7 +963,7 @@ close_more:
 			" while the maximum\n"
 			"InnoDB: allowed value would be %lu.\n"
 			"InnoDB: You may need to raise the value of"
-			" innodb_max_files_open in\n"
+			" innodb_open_files in\n"
 			"InnoDB: my.cnf.\n",
 			(ulong) fil_system->n_open,
 			(ulong) fil_system->max_n_open);
@@ -1535,7 +1543,7 @@ fil_open_log_and_system_tablespace_files
 					fprintf(stderr,
 						"InnoDB: Warning: you must"
 						" raise the value of"
-						" innodb_max_open_files in\n"
+						" innodb_open_files in\n"
 						"InnoDB: my.cnf! Remember that"
 						" InnoDB keeps all log files"
 						" and all system\n"
@@ -2923,7 +2931,6 @@ fil_open_single_table_tablespace(
 	byte*		page;
 	ulint		space_id;
 	ulint		space_flags;
-	ibool		ret		= TRUE;
 
 	filepath = fil_make_ibd_name(name, FALSE);
 
@@ -3001,7 +3008,7 @@ fil_open_single_table_tablespace(
 			(ulong) space_id, (ulong) space_flags,
 			(ulong) id, (ulong) flags);
 
-		ret = FALSE;
+		success = FALSE;
 
 		goto func_exit;
 	}
@@ -3021,7 +3028,7 @@ func_exit:
 	os_file_close(file);
 	mem_free(filepath);
 
-	return(ret);
+	return(success);
 }
 #endif /* !UNIV_HOTBACKUP */
 
@@ -3299,7 +3306,17 @@ fil_load_single_table_tablespace(
 
 	if (!success) {
 
-		goto func_exit;
+		if (srv_force_recovery > 0) {
+			fprintf(stderr,
+				"InnoDB: innodb_force_recovery"
+				" was set to %lu. Continuing crash recovery\n"
+				"InnoDB: even though the tablespace creation"
+				" of this table failed.\n",
+				srv_force_recovery);
+			goto func_exit;
+		}
+
+		exit(1);
 	}
 
 	/* We do not use the size information we have about the file, because

=== modified file 'storage/innodb_plugin/fsp/fsp0fsp.c'
--- a/storage/innodb_plugin/fsp/fsp0fsp.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/fsp/fsp0fsp.c	2009-10-09 14:13:15 +0000
@@ -232,6 +232,9 @@ the extent are free and which contain ol
 #define	XDES_ARR_OFFSET		(FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
 
 #ifndef UNIV_HOTBACKUP
+/* Flag to indicate if we have printed the tablespace full error. */
+static ibool fsp_tbs_full_error_printed = FALSE;
+
 /**********************************************************************//**
 Returns an extent to the free list of a space. */
 static
@@ -1099,7 +1102,7 @@ fsp_header_inc_size(
 
 /**********************************************************************//**
 Gets the current free limit of the system tablespace.  The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
 free list for allocation.  The space above that address is initialized
 to zero.  Sets also the global variable log_fsp_current_free_limit.
 @return	free limit in megabytes */
@@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
 
 	if (space == 0 && !srv_auto_extend_last_data_file) {
 
+		/* We print the error message only once to avoid
+		spamming the error log. Note that we don't need
+		to reset the flag to FALSE as dealing with this
+		error requires server restart. */
+		if (fsp_tbs_full_error_printed == FALSE) {
+			fprintf(stderr,
+				"InnoDB: Error: Data file(s) ran"
+				" out of space.\n"
+				"Please add another data file or"
+				" use \'autoextend\' for the last"
+				" data file.\n");
+			fsp_tbs_full_error_printed = TRUE;
+		}
 		return(FALSE);
 	}
 
@@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
 		if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
 			/* This is used */
 
+			ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+			      == FSEG_MAGIC_N_VALUE);
 			return(i);
 		}
 	}
@@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
 
 			return(i);
 		}
+
+		ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+		      == FSEG_MAGIC_N_VALUE);
 	}
 
 	return(ULINT_UNDEFINED);
@@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
 			      page + FSEG_INODE_PAGE_NODE, mtr);
 	}
 
+	ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
+	      || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 	return(inode);
 }
 
@@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
 	}
 
 	mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
-	mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
+	mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
 
 	if (ULINT_UNDEFINED
 	    == fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
@@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
 
 /**********************************************************************//**
 Returns the file segment inode, page x-latched.
-@return	segment inode, page x-latched */
+@return	segment inode, page x-latched; NULL if the inode is free */
 static
 fseg_inode_t*
-fseg_inode_get(
-/*===========*/
+fseg_inode_try_get(
+/*===============*/
 	fseg_header_t*	header,	/*!< in: segment header */
 	ulint		space,	/*!< in: space id */
 	ulint		zip_size,/*!< in: compressed page size in bytes
@@ -2054,12 +2077,38 @@ fseg_inode_get(
 
 	inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
 
-	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
+	if (UNIV_UNLIKELY
+	    (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
+
+		inode = NULL;
+	} else {
+		ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+		      == FSEG_MAGIC_N_VALUE);
+	}
 
 	return(inode);
 }
 
 /**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return	segment inode, page x-latched */
+static
+fseg_inode_t*
+fseg_inode_get(
+/*===========*/
+	fseg_header_t*	header,	/*!< in: segment header */
+	ulint		space,	/*!< in: space id */
+	ulint		zip_size,/*!< in: compressed page size in bytes
+				or 0 for uncompressed pages */
+	mtr_t*		mtr)	/*!< in: mtr handle */
+{
+	fseg_inode_t*	inode
+		= fseg_inode_try_get(header, space, zip_size, mtr);
+	ut_a(inode);
+	return(inode);
+}
+
+/**********************************************************************//**
 Gets the page number from the nth fragment page slot.
 @return	page number, FIL_NULL if not in use */
 UNIV_INLINE
@@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
 	ut_ad(inode && mtr);
 	ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
 	ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 	return(mach_read_from_4(inode + FSEG_FRAG_ARR
 				+ n * FSEG_FRAG_SLOT_SIZE));
 }
@@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
 	ut_ad(inode && mtr);
 	ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
 	ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 
 	mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
 			 page_no, MLOG_4BYTES, mtr);
@@ -2451,6 +2502,8 @@ fseg_fill_free_list(
 		xdes_set_state(descr, XDES_FSEG, mtr);
 
 		seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
+		ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+		      == FSEG_MAGIC_N_VALUE);
 		mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
 
 		flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
@@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
 	fil_addr_t	first;
 
 	ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 
 	if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
 		/* Segment free list is not empty, allocate from it */
@@ -3136,6 +3190,8 @@ fseg_mark_page_used(
 
 	ut_ad(seg_inode && mtr);
 	ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+	ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+	      == FSEG_MAGIC_N_VALUE);
 
 	descr = xdes_get_descriptor(space, zip_size, page, mtr);
 
@@ -3373,6 +3429,8 @@ fseg_free_extent(
 	ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
 	ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
 				mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
+	ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+	      == FSEG_MAGIC_N_VALUE);
 
 	first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
 
@@ -3463,7 +3521,13 @@ fseg_free_step(
 	ut_a(descr);
 	ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
 			  header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
-	inode = fseg_inode_get(header, space, zip_size, mtr);
+	inode = fseg_inode_try_get(header, space, zip_size, mtr);
+
+	if (UNIV_UNLIKELY(inode == NULL)) {
+		fprintf(stderr, "double free of inode from %u:%u\n",
+			(unsigned) space, (unsigned) header_page);
+		return(TRUE);
+	}
 
 	descr = fseg_get_first_extent(inode, space, zip_size, mtr);
 
@@ -3587,6 +3651,7 @@ fseg_get_first_extent(
 	ut_ad(inode && mtr);
 
 	ut_ad(space == page_get_space_id(page_align(inode)));
+	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 
 	first = fil_addr_null;
 
@@ -3801,6 +3866,7 @@ fseg_print_low(
 		(ulong) reserved, (ulong) used, (ulong) n_full,
 		(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
 		(ulong) n_used);
+	ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
 }
 
 #ifdef UNIV_BTR_PRINT

=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc	2009-08-04 08:02:48 +0000
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	2009-10-09 14:13:15 +0000
@@ -72,6 +72,7 @@ with this program; if not, write to the 
 /* Include necessary InnoDB headers */
 extern "C" {
 #include "univ.i"
+#include "buf0lru.h"
 #include "btr0sea.h"
 #include "os0file.h"
 #include "os0thread.h"
@@ -106,6 +107,9 @@ extern "C" {
 #include "i_s.h"
 
 #ifndef MYSQL_SERVER
+# ifndef MYSQL_PLUGIN_IMPORT
+#  define MYSQL_PLUGIN_IMPORT /* nothing */
+# endif /* MYSQL_PLUGIN_IMPORT */
 /* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
 is defined the same in both builds: the MySQL server and the InnoDB plugin. */
 extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
@@ -152,6 +156,10 @@ static ulong innobase_write_io_threads;
 
 static long long innobase_buffer_pool_size, innobase_log_file_size;
 
+/** Percentage of the buffer pool to reserve for 'old' blocks.
+Connected to buf_LRU_old_ratio. */
+static uint innobase_old_blocks_pct;
+
 /* The default values for the following char* start-up parameters
 are determined in innobase_init below: */
 
@@ -166,9 +174,7 @@ file formats in the configuration file, 
 of the supported file formats during runtime. */
 static char*	innobase_file_format_check		= NULL;
 
-/* The following has a misleading name: starting from 4.0.5, this also
-affects Windows: */
-static char*	innobase_unix_file_flush_method		= NULL;
+static char*	innobase_file_flush_method		= NULL;
 
 /* Below we have boolean-valued start-up parameters, and their default
 values */
@@ -214,15 +220,34 @@ static void free_share(INNOBASE_SHARE *s
 static int innobase_close_connection(handlerton *hton, THD* thd);
 static int innobase_commit(handlerton *hton, THD* thd, bool all);
 static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd, 
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd, 
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
            void *savepoint);
 static handler *innobase_create_handler(handlerton *hton,
                                         TABLE_SHARE *table,
                                         MEM_ROOT *mem_root);
 
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+					/* out: true if index name matches a
+					reserved name */
+	const trx_t*	trx,		/* in: InnoDB transaction handle */
+	const TABLE*	form,		/* in: information on table
+					columns and indexes */
+	const char*	norm_name);	/* in: table name */
+
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
 /** @brief Initialize the default value of innodb_commit_concurrency.
 
 Once InnoDB is running, the innodb_commit_concurrency must not change
@@ -492,10 +517,10 @@ static SHOW_VAR innodb_status_variables[
   (char*) &export_vars.innodb_buffer_pool_pages_misc,	  SHOW_LONG},
   {"buffer_pool_pages_total",
   (char*) &export_vars.innodb_buffer_pool_pages_total,	  SHOW_LONG},
-  {"buffer_pool_read_ahead_rnd",
-  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
-  {"buffer_pool_read_ahead_seq",
-  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
+  {"buffer_pool_read_ahead",
+  (char*) &export_vars.innodb_buffer_pool_read_ahead,	  SHOW_LONG},
+  {"buffer_pool_read_ahead_evicted",
+  (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
   {"buffer_pool_read_requests",
   (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
   {"buffer_pool_reads",
@@ -865,17 +890,14 @@ convert_error_code_to_mysql(
 		return(ER_PRIMARY_CANT_HAVE_NULL);
 
 	case DB_TOO_MANY_CONCURRENT_TRXS:
-		/* Once MySQL add the appropriate code to errmsg.txt then
-		we can get rid of this #ifdef. NOTE: The code checked by
-		the #ifdef is the suggested name for the error condition
-		and the actual error code name could very well be different.
-		This will require some monitoring, ie. the status
-		of this request on our part.*/
-#ifdef ER_TOO_MANY_CONCURRENT_TRXS
-		return(ER_TOO_MANY_CONCURRENT_TRXS);
-#else
+		/* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
+		available in 5.1.38 and later, but the plugin should still
+		work with previous versions of MySQL. */
+#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
+		return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
+#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 		return(HA_ERR_RECORD_FILE_FULL);
-#endif
+#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 	case DB_UNSUPPORTED:
 		return(HA_ERR_UNSUPPORTED);
 	}
@@ -949,7 +971,23 @@ innobase_get_cset_width(
 		*mbminlen = cs->mbminlen;
 		*mbmaxlen = cs->mbmaxlen;
 	} else {
-		ut_a(cset == 0);
+		THD*	thd = current_thd;
+
+		if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
+
+			/* Fix bug#46256: allow tables to be dropped if the
+			collation is not found, but issue a warning. */
+			if ((global_system_variables.log_warnings)
+			    && (cset != 0)){
+
+				sql_print_warning(
+					"Unknown collation #%lu.", cset);
+			}
+		} else {
+
+			ut_a(cset == 0);
+		}
+
 		*mbminlen = *mbmaxlen = 0;
 	}
 }
@@ -2151,7 +2189,7 @@ innobase_change_buffering_inited_ok:
 
 	/* --------------------------------------------------*/
 
-	srv_file_flush_method_str = innobase_unix_file_flush_method;
+	srv_file_flush_method_str = innobase_file_flush_method;
 
 	srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
 	srv_n_log_files = (ulint) innobase_log_files_in_group;
@@ -2206,6 +2244,9 @@ innobase_change_buffering_inited_ok:
 	ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
 	srv_latin1_ordering = my_charset_latin1.sort_order;
 
+	innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+		innobase_old_blocks_pct, FALSE);
+
 	innobase_commit_concurrency_init_default();
 
 	/* Since we in this module access directly the fields of a trx
@@ -2459,6 +2500,19 @@ retry:
 			}
 		}
 
+		/* The following calls to read the MySQL binary log
+		file name and the position return consistent results:
+		1) Other InnoDB transactions cannot intervene between
+		these calls as we are holding prepare_commit_mutex.
+		2) Binary logging of other engines is not relevant
+		to InnoDB as all InnoDB requires is that committing
+		InnoDB transactions appear in the same order in the
+		MySQL binary log as they appear in InnoDB logs.
+		3) A MySQL log file rotation cannot happen because
+		MySQL protects against this by having a counter of
+		transactions in prepared state and it only allows
+		a rotation when the counter drops to zero. See
+		LOCK_prep_xids and COND_prep_xids in log.cc. */
 		trx->mysql_log_file_name = mysql_bin_log_file_name();
 		trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
 
@@ -3105,7 +3159,7 @@ retry:
 
 		if (is_part) {
 			sql_print_error("Failed to open table %s after "
-					"%lu attemtps.\n", norm_name,
+					"%lu attempts.\n", norm_name,
 					retries);
 		}
 
@@ -5006,6 +5060,11 @@ ha_innobase::index_read(
 
 	index = prebuilt->index;
 
+	if (UNIV_UNLIKELY(index == NULL)) {
+		prebuilt->index_usable = FALSE;
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	/* Note that if the index for which the search template is built is not
 	necessarily prebuilt->index, but can also be the clustered index */
 
@@ -5165,6 +5224,7 @@ ha_innobase::change_active_index(
 	if (UNIV_UNLIKELY(!prebuilt->index)) {
 		sql_print_warning("InnoDB: change_active_index(%u) failed",
 				  keynr);
+		prebuilt->index_usable = FALSE;
 		DBUG_RETURN(1);
 	}
 
@@ -5657,6 +5717,28 @@ create_table_def(
 			}
 		}
 
+		/* First check whether the column to be added has a
+		system reserved name. */
+		if (dict_col_name_is_reserved(field->field_name)){
+			push_warning_printf(
+				(THD*) trx->mysql_thd,
+				MYSQL_ERROR::WARN_LEVEL_ERROR,
+				ER_CANT_CREATE_TABLE,
+				"Error creating table '%s' with "
+				"column name '%s'. '%s' is a "
+				"reserved name. Please try to "
+				"re-create the table with a "
+				"different column name.",
+				table->name, (char*) field->field_name,
+				(char*) field->field_name);
+
+			dict_mem_table_free(table);
+			trx_commit_for_mysql(trx);
+
+			error = DB_ERROR;
+			goto error_ret;
+		}
+
 		dict_mem_table_add_col(table, table->heap,
 			(char*) field->field_name,
 			col_type,
@@ -5670,6 +5752,7 @@ create_table_def(
 
 	error = row_create_table_for_mysql(table, trx);
 
+error_ret:
 	error = convert_error_code_to_mysql(error, flags, NULL);
 
 	DBUG_RETURN(error);
@@ -5708,6 +5791,9 @@ create_index(
 
 	n_fields = key->key_parts;
 
+	/* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+	ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
 	ind_type = 0;
 
 	if (key_num == form->s->primary_key) {
@@ -5816,8 +5902,8 @@ create_clustered_index_when_no_primary(
 
 	/* We pass 0 as the space id, and determine at a lower level the space
 	id where to store the table */
-
-	index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+	index = dict_mem_index_create(table_name,
+				      innobase_index_reserve_name,
 				      0, DICT_CLUSTERED, 0);
 
 	error = row_create_index_for_mysql(index, trx, NULL);
@@ -6243,14 +6329,6 @@ ha_innobase::create(
 		flags = DICT_TF_COMPACT;
 	}
 
-	error = create_table_def(trx, form, norm_name,
-		create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
-		flags);
-
-	if (error) {
-		goto cleanup;
-	}
-
 	/* Look for a primary key */
 
 	primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -6262,6 +6340,22 @@ ha_innobase::create(
 
 	ut_a(primary_key_no == -1 || primary_key_no == 0);
 
+	/* Check for name conflicts (with reserved name) for
+	any user indices to be created. */
+	if (innobase_index_name_is_reserved(trx, form, norm_name)) {
+		error = -1;
+		goto cleanup;
+	}
+
+	error = create_table_def(trx, form, norm_name,
+		create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+		flags);
+
+	if (error) {
+		goto cleanup;
+	}
+
+
 	/* Create the keys */
 
 	if (form->s->keys == 0 || primary_key_no == -1) {
@@ -8446,6 +8540,7 @@ ha_innobase::store_lock(
 		    && isolation_level != TRX_ISO_SERIALIZABLE
 		    && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
 		    && (sql_command == SQLCOM_INSERT_SELECT
+			|| sql_command == SQLCOM_REPLACE_SELECT
 			|| sql_command == SQLCOM_UPDATE
 			|| sql_command == SQLCOM_CREATE_TABLE)) {
 
@@ -8453,10 +8548,11 @@ ha_innobase::store_lock(
 			option set or this session is using READ COMMITTED
 			isolation level and isolation level of the transaction
 			is not set to serializable and MySQL is doing
-			INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
-			CREATE  ... SELECT... without FOR UPDATE or
-			IN SHARE MODE in select, then we use consistent
-			read for select. */
+			INSERT INTO...SELECT or REPLACE INTO...SELECT
+			or UPDATE ... = (SELECT ...) or CREATE  ...
+			SELECT... without FOR UPDATE or IN SHARE
+			MODE in select, then we use consistent read
+			for select. */
 
 			prebuilt->select_lock_type = LOCK_NONE;
 			prebuilt->stored_select_lock_type = LOCK_NONE;
@@ -9612,6 +9708,25 @@ innodb_adaptive_hash_index_update(
 	}
 }
 
+/****************************************************************//**
+Update the system variable innodb_old_blocks_pct using the "saved"
+value. This function is registered as a callback with MySQL. */
+static
+void
+innodb_old_blocks_pct_update(
+/*=========================*/
+	THD*				thd,	/*!< in: thread handle */
+	struct st_mysql_sys_var*	var,	/*!< in: pointer to
+						system variable */
+	void*				var_ptr,/*!< out: where the
+						formal string goes */
+	const void*			save)	/*!< in: immediate result
+						from check function */
+{
+	innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+		*static_cast<const uint*>(save), TRUE);
+}
+
 /*************************************************************//**
 Check if it is a valid value of innodb_change_buffering.  This function is
 registered as a callback with MySQL.
@@ -9685,6 +9800,46 @@ static int show_innodb_vars(THD *thd, SH
   return 0;
 }
 
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+					/* out: true if an index name
+					matches the reserved name */
+	const trx_t*	trx,		/* in: InnoDB transaction handle */
+	const TABLE*	form,		/* in: information on table
+					columns and indexes */
+	const char*	norm_name)	/* in: table name */
+{
+	KEY*		key;
+	uint		key_num;	/* index number */
+
+	for (key_num = 0; key_num < form->s->keys; key_num++) {
+		key = form->key_info + key_num;
+
+		if (innobase_strcasecmp(key->name,
+					innobase_index_reserve_name) == 0) {
+			/* Push warning to mysql */
+			push_warning_printf((THD*) trx->mysql_thd,
+					    MYSQL_ERROR::WARN_LEVEL_ERROR,
+					    ER_CANT_CREATE_TABLE,
+					    "Cannot Create Index with name "
+					    "'%s'. The name is reserved "
+					    "for the system default primary "
+					    "index.",
+					    innobase_index_reserve_name);
+
+			return(true);
+		}
+	}
+
+	return(false);
+}
+
 static SHOW_VAR innodb_status_variables_export[]= {
   {"Innodb",                   (char*) &show_innodb_vars, SHOW_FUNC},
   {NullS, NullS, SHOW_LONG}
@@ -9753,7 +9908,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_t
   " or 2 (write at commit, flush once per second).",
   NULL, NULL, 1, 0, 2, 0);
 
-static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
+static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
   "With which method to flush data.", NULL, NULL, NULL);
 
@@ -9849,7 +10004,7 @@ static MYSQL_SYSVAR_ULONG(concurrency_ti
   NULL, NULL, 500L, 1L, ~0L, 0);
 
 static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
-  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
   "Number of file I/O threads in InnoDB.",
   NULL, NULL, 4, 4, 64, 0);
 
@@ -9888,6 +10043,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_gr
   "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
   NULL, NULL, 1, 1, 10, 0);
 
+static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
+  PLUGIN_VAR_RQCMDARG,
+  "Percentage of the buffer pool to reserve for 'old' blocks.",
+  NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
+
+static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
+  PLUGIN_VAR_RQCMDARG,
+  "Move blocks to the 'new' end of the buffer pool if the first access"
+  " was at least this many milliseconds ago."
+  " The timeout is disabled if 0 (the default).",
+  NULL, NULL, 0, 0, UINT_MAX32, 0);
+
 static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
   "How many files at the maximum InnoDB keeps open at the same time.",
@@ -9986,6 +10153,8 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(adaptive_flushing),
   MYSQL_SYSVAR(max_purge_lag),
   MYSQL_SYSVAR(mirrored_log_groups),
+  MYSQL_SYSVAR(old_blocks_pct),
+  MYSQL_SYSVAR(old_blocks_time),
   MYSQL_SYSVAR(open_files),
   MYSQL_SYSVAR(rollback_on_timeout),
   MYSQL_SYSVAR(stats_on_metadata),

=== modified file 'storage/innodb_plugin/handler/handler0alter.cc'
--- a/storage/innodb_plugin/handler/handler0alter.cc	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/handler/handler0alter.cc	2009-10-08 10:00:49 +0000
@@ -663,7 +663,7 @@ ha_innobase::add_index(
 	if (UNIV_UNLIKELY(error)) {
 err_exit:
 		mem_heap_free(heap);
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		trx_free_for_mysql(trx);
 		trx_commit_for_mysql(prebuilt->trx);
 		DBUG_RETURN(error);
@@ -801,7 +801,7 @@ error_handling:
 	alter table t drop index b, add index (b);
 
 	The fix will have to parse the SQL and note that the index
-	being added has the same name as the the one being dropped and
+	being added has the same name as the one being dropped and
 	ignore that in the dup index check.*/
 	//dict_table_check_for_dup_indexes(prebuilt->table);
 #endif
@@ -863,6 +863,7 @@ error_handling:
 		indexed_table->n_mysql_handles_opened++;
 
 		error = row_merge_drop_table(trx, innodb_table);
+		innodb_table = indexed_table;
 		goto convert_error;
 
 	case DB_TOO_BIG_RECORD:

=== removed file 'storage/innodb_plugin/handler/handler0vars.h'
--- a/storage/innodb_plugin/handler/handler0vars.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/handler/handler0vars.h	1970-01-01 00:00:00 +0000
@@ -1,69 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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 handler/handler0vars.h
-This file contains accessor functions for dynamic plugin on Windows.
-***********************************************************************/
-
-#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/*******************************************************************//**
-This is a list of externals that can not be resolved by delay loading.
-They have to be resolved indirectly via their addresses in the .map file.
-All of them are external variables. */
-extern	CHARSET_INFO*		wdl_my_charset_bin;
-extern	CHARSET_INFO*		wdl_my_charset_latin1;
-extern	CHARSET_INFO*		wdl_my_charset_filename;
-extern	CHARSET_INFO**		wdl_system_charset_info;
-extern	CHARSET_INFO**		wdl_default_charset_info;
-extern	CHARSET_INFO**		wdl_all_charsets;
-extern	system_variables*	wdl_global_system_variables;
-extern	char*			wdl_mysql_real_data_home;
-extern	char**			wdl_mysql_data_home;
-extern	char**			wdl_tx_isolation_names;
-extern	char**			wdl_binlog_format_names;
-extern	char*			wdl_reg_ext;
-extern	pthread_mutex_t*	wdl_LOCK_thread_count;
-extern	key_map*		wdl_key_map_full;
-extern	MY_TMPDIR*		wdl_mysql_tmpdir_list;
-extern	bool*			wdl_mysqld_embedded;
-extern	uint*			wdl_lower_case_table_names;
-extern	ulong*			wdl_specialflag;
-extern	int*			wdl_my_umask;
-
-#define my_charset_bin		(*wdl_my_charset_bin)
-#define my_charset_latin1	(*wdl_my_charset_latin1)
-#define my_charset_filename	(*wdl_my_charset_filename)
-#define system_charset_info	(*wdl_system_charset_info)
-#define default_charset_info	(*wdl_default_charset_info)
-#define all_charsets		(wdl_all_charsets)
-#define global_system_variables	(*wdl_global_system_variables)
-#define mysql_real_data_home	(wdl_mysql_real_data_home)
-#define mysql_data_home		(*wdl_mysql_data_home)
-#define tx_isolation_names	(wdl_tx_isolation_names)
-#define binlog_format_names	(wdl_binlog_format_names)
-#define reg_ext			(wdl_reg_ext)
-#define LOCK_thread_count	(*wdl_LOCK_thread_count)
-#define key_map_full		(*wdl_key_map_full)
-#define mysql_tmpdir_list	(*wdl_mysql_tmpdir_list)
-#define mysqld_embedded		(*wdl_mysqld_embedded)
-#define lower_case_table_names	(*wdl_lower_case_table_names)
-#define specialflag		(*wdl_specialflag)
-#define my_umask		(*wdl_my_umask)
-
-#endif

=== removed file 'storage/innodb_plugin/handler/win_delay_loader.cc'
--- a/storage/innodb_plugin/handler/win_delay_loader.cc	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/handler/win_delay_loader.cc	1970-01-01 00:00:00 +0000
@@ -1,1024 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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 handler/win_delay_loader.cc
-This file contains functions that implement the delay loader on Windows.
-
-This is a customized version of delay loader with limited functionalities.
-It does not support:
-
-* (manual) unloading
-* multiple delay loaded DLLs
-* multiple loading of the same DLL
-
-This delay loader is used only by the InnoDB plugin. Other components (DLLs)
-can still use the default delay loader, provided by MSVC.
-
-Several acronyms used by Microsoft:
- * IAT: import address table
- * INT: import name table
- * RVA: Relative Virtual Address
-
-See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
-PE format.
-***********************************************************************/
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <delayimp.h>
-# include <mysql_priv.h>
-
-extern "C" {
-# include "univ.i"
-# include "hash0hash.h"
-}
-
-/*******************************************************************//**
-This following contains a list of externals that can not be resolved by
-delay loading. They have to be resolved indirectly via their addresses
-in the .map file. All of them are external variables. */
-CHARSET_INFO*		wdl_my_charset_bin;
-CHARSET_INFO*		wdl_my_charset_latin1;
-CHARSET_INFO*		wdl_my_charset_filename;
-CHARSET_INFO**		wdl_system_charset_info;
-CHARSET_INFO**		wdl_default_charset_info;
-CHARSET_INFO**		wdl_all_charsets;
-system_variables*	wdl_global_system_variables;
-char*			wdl_mysql_real_data_home;
-char**			wdl_mysql_data_home;
-char**			wdl_tx_isolation_names;
-char**			wdl_binlog_format_names;
-char*			wdl_reg_ext;
-pthread_mutex_t*	wdl_LOCK_thread_count;
-key_map*		wdl_key_map_full;
-MY_TMPDIR*		wdl_mysql_tmpdir_list;
-bool*			wdl_mysqld_embedded;
-uint*			wdl_lower_case_table_names;
-ulong*			wdl_specialflag;
-int*			wdl_my_umask;
-
-/*******************************************************************//**
-The preferred load-address defined in PE (portable executable format). */
-#if defined(_M_IA64)
-#pragma section(".base", long, read)
-extern "C"
-__declspec(allocate(".base"))
-const IMAGE_DOS_HEADER __ImageBase;
-#else
-extern "C"
-const IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-/*******************************************************************//**
-A template function for converting a relative address (RVA) to an
-absolute address (VA). This is due to the pointers in the delay
-descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms.
-@return	absolute virtual address */
-template <class X>
-X PFromRva(
-/*=======*/
-	RVA	rva)	/*!< in: relative virtual address */
-{
-	return X(PBYTE(&__ImageBase) + rva);
-}
-
-/*******************************************************************//**
-Convert to the old format for convenience. The structure as well as its
-element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr
-{
-	DWORD		grAttrs;	/*!< attributes */
-	LPCSTR		szName;		/*!< pointer to dll name */
-	HMODULE*	phmod;		/*!< address of module handle */
-	PImgThunkData	pIAT;		/*!< address of the IAT */
-	PCImgThunkData	pINT;		/*!< address of the INT */
-	PCImgThunkData	pBoundIAT;	/*!< address of the optional bound IAT */
-	PCImgThunkData	pUnloadIAT;	/*!< address of optional copy of
-					   original IAT */
-	DWORD		dwTimeStamp;	/*!< 0 if not bound,
-					   otherwise date/time stamp of DLL
-					   bound to (Old BIND) */
-};
-
-typedef struct map_hash_chain_struct	map_hash_chain_t;
-
-struct map_hash_chain_struct {
-	char*			symbol;	/*!< pointer to a symbol */
-	ulint			value;	/*!< address of the symbol */
-	map_hash_chain_t*	next;	/*!< pointer to the next cell
-					in the same folder. */
-	map_hash_chain_t*	chain;	/*!< a linear chain used for
-					cleanup. */
-};
-
-static HMODULE				my_hmod = 0;
-static struct hash_table_struct*	m_htbl = NULL ;
-static map_hash_chain_t*		chain_header = NULL;
-static ibool				wdl_init = FALSE;
-const ulint				MAP_HASH_CELLS_NUM = 10000;
-
-#ifndef DBUG_OFF
-/*******************************************************************//**
-In the dynamic plugin, it is required to call the following dbug functions
-in the server:
-	_db_pargs_
-	_db_doprnt_
-	_db_enter_
-	_db_return_
-	_db_dump_
-
-The plugin will get those function pointers during the initialization. */
-typedef void (__cdecl* pfn_db_enter_)(
-	const char*	_func_,
-	const char*	_file_,
-	uint		_line_,
-	const char**	_sfunc_,
-	const char**	_sfile_,
-	uint*		_slevel_,
-	char***);
-
-typedef void (__cdecl* pfn_db_return_)(
-	uint		_line_,
-	const char**	_sfunc_,
-	const char**	_sfile_,
-	uint*		_slevel_);
-
-typedef void (__cdecl* pfn_db_pargs_)(
-	uint		_line_,
-	const char*	keyword);
-
-typedef void (__cdecl* pfn_db_doprnt_)(
-	const char*	format,
-	...);
-
-typedef void (__cdecl* pfn_db_dump_)(
-	uint			_line_,
-	const char*		keyword,
-	const unsigned char*	memory,
-	size_t			length);
-
-static pfn_db_enter_	wdl_db_enter_;
-static pfn_db_return_	wdl_db_return_;
-static pfn_db_pargs_	wdl_db_pargs_;
-static pfn_db_doprnt_	wdl_db_doprnt_;
-static pfn_db_dump_	wdl_db_dump_;
-#endif /* !DBUG_OFF */
-
-/*************************************************************//**
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-
-This is the same function as hash_create in hash0hash.c, except the
-memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet.
-@return	own: created hash table */
-static
-hash_table_t*
-wdl_hash_create(
-/*============*/
-	ulint	n)	/*!< in: number of array cells */
-{
-	hash_cell_t*	array;
-	ulint		prime;
-	hash_table_t*	table;
-
-	prime = ut_find_prime(n);
-
-	table = (hash_table_t*) malloc(sizeof(hash_table_t));
-	if (table == NULL) {
-		return(NULL);
-	}
-
-	array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
-	if (array == NULL) {
-		free(table);
-		return(NULL);
-	}
-
-	table->array = array;
-	table->n_cells = prime;
-	table->n_mutexes = 0;
-	table->mutexes = NULL;
-	table->heaps = NULL;
-	table->heap = NULL;
-	table->magic_n = HASH_TABLE_MAGIC_N;
-
-	/* Initialize the cell array */
-	hash_table_clear(table);
-
-	return(table);
-}
-
-/*************************************************************//**
-Frees a hash table. */
-static
-void
-wdl_hash_table_free(
-/*================*/
-	hash_table_t*	table)	/*!< in, own: hash table */
-{
-	ut_a(table != NULL);
-	ut_a(table->mutexes == NULL);
-
-	free(table->array);
-	free(table);
-}
-
-/*******************************************************************//**
-Function for calculating the count of imports given the base of the IAT.
-@return	number of imports */
-static
-ulint
-wdl_import_count(
-/*=============*/
-	PCImgThunkData	pitd_base)	/*!< in: base of the IAT */
-{
-	ulint		ret = 0;
-	PCImgThunkData	pitd = pitd_base;
-
-	while (pitd->u1.Function) {
-		pitd++;
-		ret++;
-	}
-
-	return(ret);
-}
-
-/*******************************************************************//**
-Read Mapfile to a hashtable for faster access
-@return	TRUE if the mapfile is loaded successfully. */
-static
-ibool
-wdl_load_mapfile(
-/*=============*/
-	const char*	filename)	/*!< in: name of the mapfile. */
-{
-	FILE*		fp;
-	const size_t	nSize = 256;
-	char		tmp_buf[nSize];
-	char*		func_name;
-	char*		func_addr;
-	ulint		load_addr = 0;
-	ibool		valid_load_addr = FALSE;
-#ifdef _WIN64
-	const char*	tmp_string = " Preferred load address is %16llx";
-#else
-	const char*	tmp_string = " Preferred load address is %08x";
-#endif
-
-	fp = fopen(filename, "r");
-	if (fp == NULL) {
-
-		return(FALSE);
-	}
-
-	/* Check whether to create the hashtable */
-	if (m_htbl == NULL) {
-
-		m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
-
-		if (m_htbl == NULL) {
-
-			fclose(fp);
-			return(FALSE);
-		}
-	}
-
-	/* Search start of symbol list and get the preferred load address */
-	while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
-
-		if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
-
-			valid_load_addr = TRUE;
-		}
-
-		if (strstr(tmp_buf, "Rva+Base") != NULL) {
-
-			break;
-		}
-	}
-
-	if (valid_load_addr == FALSE) {
-
-		/* No "Preferred load address", the map file is wrong. */
-		fclose(fp);
-		return(FALSE);
-	}
-
-	/* Read symbol list */
-	while (fgets(tmp_buf, sizeof(tmp_buf), fp))
-	{
-		map_hash_chain_t*	map_cell;
-		ulint			map_fold;
-
-		if (*tmp_buf == 0) {
-
-			continue;
-		}
-
-		func_name = strtok(tmp_buf, " ");
-		func_name = strtok(NULL, " ");
-		func_addr = strtok(NULL, " ");
-
-		if (func_name && func_addr) {
-
-			ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
-			if (*func_name == '_') {
-
-				func_name++;
-			}
-
-			map_cell = (map_hash_chain_t*)
-				   malloc(sizeof(map_hash_chain_t));
-			if (map_cell == NULL) {
-				return(FALSE);
-			}
-
-			/* Chain all cells together */
-			map_cell->chain = chain_header;
-			chain_header = map_cell;
-
-			map_cell->symbol = strdup(func_name);
-			map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
-					  - load_addr;
-			map_fold = ut_fold_string(map_cell->symbol);
-
-			HASH_INSERT(map_hash_chain_t,
-				    next,
-				    m_htbl,
-				    map_fold,
-				    map_cell);
-		}
-	}
-
-	fclose(fp);
-
-	return(TRUE);
-}
-
-/*************************************************************//**
-Cleanup.during DLL unload */
-static
-void
-wdl_cleanup(void)
-/*=============*/
-{
-	while (chain_header != NULL) {
-		map_hash_chain_t*	tmp;
-
-		tmp = chain_header->chain;
-		free(chain_header->symbol);
-		free(chain_header);
-		chain_header = tmp;
-	}
-
-	if (m_htbl != NULL) {
-
-		wdl_hash_table_free(m_htbl);
-	}
-}
-
-/*******************************************************************//**
-Load the mapfile mysqld.map.
-@return	the module handle */
-static
-HMODULE
-wdl_get_mysqld_mapfile(void)
-/*========================*/
-{
-	char	file_name[MAX_PATH];
-	char*	ext;
-	ulint	err;
-
-	if (my_hmod == 0) {
-
-		size_t	nSize = MAX_PATH - strlen(".map") -1;
-
-		/* First find out the name of current executable */
-		my_hmod = GetModuleHandle(NULL);
-		if (my_hmod == 0) {
-
-			return(my_hmod);
-		}
-
-		err = GetModuleFileName(my_hmod, file_name, nSize);
-		if (err == 0) {
-
-			my_hmod = 0;
-			return(my_hmod);
-		}
-
-		ext = strrchr(file_name, '.');
-		if (ext != NULL) {
-
-			*ext = 0;
-			strcat(file_name, ".map");
-
-			err = wdl_load_mapfile(file_name);
-			if (err == 0) {
-
-				my_hmod = 0;
-			}
-		} else {
-
-			my_hmod = 0;
-		}
-	}
-
-	return(my_hmod);
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported function. It follows the convention
-of GetProcAddress().
-@return	address of exported function. */
-static
-FARPROC
-wdl_get_procaddr_from_map(
-/*======================*/
-	HANDLE		m_handle,	/*!< in: module handle */
-	const char*	import_proc)	/*!< in: procedure name */
-{
-	map_hash_chain_t*	hash_chain;
-	ulint			map_fold;
-
-	map_fold = ut_fold_string(import_proc);
-	HASH_SEARCH(
-		next,
-		m_htbl,
-		map_fold,
-		map_hash_chain_t*,
-		hash_chain,
-		,
-		(ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
-	if (hash_chain == NULL) {
-
-#ifdef _WIN64
-		/* On Win64, the leading '_' may not be taken out. In this
-		case, search again without the leading '_'. */
-		if (*import_proc == '_') {
-
-			import_proc++;
-		}
-
-		map_fold = ut_fold_string(import_proc);
-		HASH_SEARCH(
-			next,
-			m_htbl,
-			map_fold,
-			map_hash_chain_t*,
-			hash_chain,
-			,
-			(ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
-		if (hash_chain == NULL) {
-#endif
-			if (wdl_init == TRUE) {
-
-				sql_print_error(
-					"InnoDB: the procedure pointer of %s"
-					" is not found.",
-					import_proc);
-			}
-
-			return(0);
-#ifdef _WIN64
-		}
-#endif
-	}
-
-	return((FARPROC) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC.
-@return	address of exported variable. */
-static
-void*
-wdl_get_varaddr_from_map(
-/*=====================*/
-	HANDLE		m_handle,		/*!< in: module handle */
-	const char*	import_variable)	/*!< in: variable name */
-{
-	map_hash_chain_t*	hash_chain;
-	ulint			map_fold;
-
-	map_fold = ut_fold_string(import_variable);
-	HASH_SEARCH(
-		next,
-		m_htbl,
-		map_fold,
-		map_hash_chain_t*,
-		hash_chain,
-		,
-		(ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
-	if (hash_chain == NULL) {
-
-#ifdef _WIN64
-		/* On Win64, the leading '_' may not be taken out. In this
-		case, search again without the leading '_'. */
-		if (*import_variable == '_') {
-
-			import_variable++;
-		}
-
-		map_fold = ut_fold_string(import_variable);
-		HASH_SEARCH(
-			next,
-			m_htbl,
-			map_fold,
-			map_hash_chain_t*,
-			hash_chain,
-			,
-			(ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
-		if (hash_chain == NULL) {
-#endif
-			if (wdl_init == TRUE) {
-
-				sql_print_error(
-					"InnoDB: the variable address of %s"
-					" is not found.",
-					import_variable);
-			}
-
-			return(0);
-#ifdef _WIN64
-		}
-#endif
-	}
-
-	return((void*) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Bind all unresolved external variables from the MySQL executable.
-@return	TRUE if successful */
-static
-bool
-wdl_get_external_variables(void)
-/*============================*/
-{
-	HMODULE	hmod = wdl_get_mysqld_mapfile();
-
-	if (hmod == 0) {
-
-		return(FALSE);
-	}
-
-#define GET_SYM(sym, var, type)					\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym);	\
-	if (var == NULL) return(FALSE)
-#ifdef _WIN64
-#define GET_SYM2(sym1, sym2, var, type)				\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym1);	\
-	if (var == NULL) return(FALSE)
-#else
-#define GET_SYM2(sym1, sym2, var, type)				\
-	var = (type*) wdl_get_varaddr_from_map(hmod, sym2);	\
-	if (var == NULL) return(FALSE)
-#endif // (_WIN64)
-#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
-#define GET_PROC_ADDR(sym)					\
-	wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
-
-	GET_C_SYM(my_charset_bin, CHARSET_INFO);
-	GET_C_SYM(my_charset_latin1, CHARSET_INFO);
-	GET_C_SYM(my_charset_filename, CHARSET_INFO);
-	GET_C_SYM(default_charset_info, CHARSET_INFO*);
-	GET_C_SYM(all_charsets, CHARSET_INFO*);
-	GET_C_SYM(my_umask, int);
-
-	GET_SYM("?global_system_variables@@3Usystem_variables@@A",
-		wdl_global_system_variables, struct system_variables);
-	GET_SYM("?mysql_real_data_home@@3PADA",
-		wdl_mysql_real_data_home, char);
-	GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
-	GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
-		wdl_LOCK_thread_count, pthread_mutex_t);
-	GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
-		wdl_key_map_full, key_map);
-	GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
-		wdl_mysql_tmpdir_list, MY_TMPDIR);
-	GET_SYM("?mysqld_embedded@@3_NA",
-		wdl_mysqld_embedded, bool);
-	GET_SYM("?lower_case_table_names@@3IA",
-		wdl_lower_case_table_names, uint);
-	GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
-
-	GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
-		 "?system_charset_info@@3PAUcharset_info_st@@A",
-		 wdl_system_charset_info, CHARSET_INFO*);
-	GET_SYM2("?mysql_data_home@@3PEADEA",
-		 "?mysql_data_home@@3PADA",
-		 wdl_mysql_data_home, char*);
-	GET_SYM2("?tx_isolation_names@@3PAPEBDA",
-		 "?tx_isolation_names@@3PAPBDA",
-		 wdl_tx_isolation_names, char*);
-	GET_SYM2("?binlog_format_names@@3PAPEBDA",
-		 "?binlog_format_names@@3PAPBDA",
-		 wdl_binlog_format_names, char*);
-
-#ifndef DBUG_OFF
-	GET_PROC_ADDR(_db_enter_);
-	GET_PROC_ADDR(_db_return_);
-	GET_PROC_ADDR(_db_pargs_);
-	GET_PROC_ADDR(_db_doprnt_);
-	GET_PROC_ADDR(_db_dump_);
-
-	/* If any of the dbug functions is not available, just make them
-	all invalid. This is the case when working with a non-debug
-	version of the server. */
-	if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
-	    || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
-	    || wdl_db_dump_ == NULL) {
-
-		wdl_db_enter_ = NULL;
-		wdl_db_return_ = NULL;
-		wdl_db_pargs_ = NULL;
-		wdl_db_doprnt_ = NULL;
-		wdl_db_dump_ = NULL;
-	}
-#endif /* !DBUG_OFF */
-
-	wdl_init = TRUE;
-	return(TRUE);
-
-#undef GET_SYM
-#undef GET_SYM2
-#undef GET_C_SYM
-#undef GET_PROC_ADDR
-}
-
-/*******************************************************************//**
-The DLL Delayed Loading Helper Function for resolving externals.
-
-The function may fail due to one of the three reasons:
-
-* Invalid parameter, which happens if the attributes in pidd aren't
-  specified correctly.
-* Failed to load the map file mysqld.map.
-* Failed to find an external name in the map file mysqld.map.
-
-Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention.
-@return	the address of the imported function */
-extern "C"
-FARPROC WINAPI
-__delayLoadHelper2(
-/*===============*/
-	PCImgDelayDescr	pidd,		/*!< in: a const pointer to a
-					ImgDelayDescr, see delayimp.h. */
-	FARPROC*	iat_entry)	/*!< in/out: A pointer to the slot in
-					the delay load import address table
-					to be updated with the address of the
-					imported function. */
-{
-	ulint		iIAT, iINT;
-	HMODULE		hmod;
-	PCImgThunkData	pitd;
-	FARPROC		fun = NULL;
-
-	/* Set up data used for the hook procs  */
-	InternalImgDelayDescr	idd = {
-				pidd->grAttrs,
-				PFromRva<LPCSTR>(pidd->rvaDLLName),
-				PFromRva<HMODULE*>(pidd->rvaHmod),
-				PFromRva<PImgThunkData>(pidd->rvaIAT),
-				PFromRva<PCImgThunkData>(pidd->rvaINT),
-				PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
-				PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
-				pidd->dwTimeStamp
-	};
-
-	DelayLoadInfo		dli = {
-				sizeof(DelayLoadInfo),
-				pidd,
-				iat_entry,
-				idd.szName,
-				{0},
-				0,
-				0,
-				0
-	};
-
-	/* Check the Delay Load Attributes, log an error of invalid
-	parameter, which happens if the attributes in pidd are not
-	specified correctly. */
-	if ((idd.grAttrs & dlattrRva) == 0) {
-
-		sql_print_error("InnoDB: invalid parameter for delay loader.");
-		return(0);
-	}
-
-	hmod = *idd.phmod;
-
-	/* Calculate the index for the IAT entry in the import address table.
-	The INT entries are ordered the same as the IAT entries so the
-	calculation can be done on the IAT side. */
-	iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
-	iINT = iIAT;
-
-	pitd = &(idd.pINT[iINT]);
-
-	dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
-
-	if (dli.dlp.fImportByName) {
-
-		dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
-			((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
-	} else {
-
-		dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
-	}
-
-	/* Now, load the mapfile, if it has not been done yet */
-	if (hmod == 0) {
-
-		hmod = wdl_get_mysqld_mapfile();
-	}
-
-	if (hmod == 0) {
-		/* LoadLibrary failed. */
-		PDelayLoadInfo	rgpdli[1] = {&dli};
-
-		dli.dwLastError = ::GetLastError();
-
-		sql_print_error(
-			"InnoDB: failed to load mysqld.map with error %d.",
-			dli.dwLastError);
-
-		return(0);
-	}
-
-	/* Store the library handle. */
-	idd.phmod = &hmod;
-
-	/* Go for the procedure now. */
-	dli.hmodCur = hmod;
-
-	if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
-
-		/* Bound imports exist, check the timestamp from the target
-		image */
-		PIMAGE_NT_HEADERS	pinh;
-
-		pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
-				+ ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-
-		if (pinh->Signature == IMAGE_NT_SIGNATURE
-		    && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
-		    && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
-
-			/* We have a decent address in the bound IAT. */
-			fun = (FARPROC) (UINT_PTR)
-					idd.pBoundIAT[iIAT].u1.Function;
-
-			if (fun) {
-
-				*iat_entry = fun;
-				return(fun);
-			}
-		}
-	}
-
-	fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
-
-	if (fun == 0) {
-
-		return(0);
-	}
-
-	*iat_entry = fun;
-	return(fun);
-}
-
-/*******************************************************************//**
-Unload a DLL that was delay loaded. This function is called by run-time.
-@return TRUE is returned if the DLL is found and the IAT matches the
-original one. */
-extern "C"
-BOOL WINAPI
-__FUnloadDelayLoadedDLL2(
-/*=====================*/
-	LPCSTR	module_name)	/*!< in: DLL name */
-{
-	return(TRUE);
-}
-
-/**************************************************************//**
-Load all imports from a DLL that was specified with the /delayload linker
-option.
-Note: this function is called by run-time. So, it has to follow Windows call
-convention.
-@return	S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
-extern "C"
-HRESULT WINAPI
-__HrLoadAllImportsForDll(
-/*=====================*/
-	LPCSTR	module_name)	/*!< in: DLL name */
-{
-	PIMAGE_NT_HEADERS	img;
-	PCImgDelayDescr		pidd;
-	IMAGE_DATA_DIRECTORY*	image_data;
-	LPCSTR			current_module;
-	HRESULT			ret = ERROR_MOD_NOT_FOUND;
-	HMODULE			hmod = (HMODULE) &__ImageBase;
-
-	img = (PIMAGE_NT_HEADERS) ((byte*) hmod
-				   + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-	image_data =
-	 &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
-
-	/* Scan the delay load IAT/INT for the DLL */
-	if (image_data->Size) {
-
-		pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
-
-		/* Check all of the listed DLLs we want to load. */
-		while (pidd->rvaDLLName) {
-
-			current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
-
-			if (stricmp(module_name, current_module) == 0) {
-
-				/* Found it, break out with pidd and
-				current_module set appropriately */
-				break;
-			}
-
-			/* To the next delay import descriptor */
-			pidd++;
-		}
-
-		if (pidd->rvaDLLName) {
-
-			/* Found a matching DLL, now process it. */
-			FARPROC*	iat_entry;
-			size_t		count;
-
-			iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
-			count = wdl_import_count((PCImgThunkData) iat_entry);
-
-			/* now load all the imports from the DLL */
-			while (count > 0) {
-
-				/* No need to check the return value */
-				__delayLoadHelper2(pidd, iat_entry);
-				iat_entry++;
-				count--;
-			}
-
-			ret = S_OK;
-		}
-	}
-
-	return ret;
-}
-
-/**************************************************************//**
-The main function of a DLL
-@return	TRUE if the call succeeds */
-BOOL
-WINAPI
-DllMain(
-/*====*/
-	HINSTANCE	hinstDLL,	/*!< in: handle to the DLL module */
-	DWORD		fdwReason,	/*!< Reason code that indicates why the
-					DLL entry-point function is being
-					called.*/
-	LPVOID		lpvReserved)	/*!< in: additional parameter based on
-					fdwReason */
-{
-	BOOL	success = TRUE;
-
-	switch (fdwReason) {
-
-	case DLL_PROCESS_ATTACH:
-		success = wdl_get_external_variables();
-		break;
-
-	case DLL_PROCESS_DETACH:
-		wdl_cleanup();
-		break;
-	}
-
-	return(success);
-}
-
-#ifndef DBUG_OFF
-/**************************************************************//**
-Process entry point to user function. It makes the call to _db_enter_
-in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
-extern "C" UNIV_INTERN
-void
-_db_enter_(
-	const char*	_func_,		/*!< in: current function name */
-	const char*	_file_,		/*!< in: current file name */
-	uint		_line_,		/*!< in: current source line number */
-	const char**	_sfunc_,	/*!< out: previous _func_ */
-	const char**	_sfile_,	/*!< out: previous _file_ */
-	uint*		_slevel_,	/*!< out: previous nesting level */
-	char***		_sframep_)	/*!< out: previous frame pointer */
-{
-	if (wdl_db_enter_ != NULL) {
-
-		wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
-			      _slevel_, _sframep_);
-	}
-}
-
-/**************************************************************//**
-Process exit from user function. It makes the call to _db_return_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_return_(
-	uint		_line_,		/*!< in: current source line number */
-	const char**	_sfunc_,	/*!< out: previous _func_ */
-	const char**	_sfile_,	/*!< out: previous _file_ */
-	uint*		_slevel_)	/*!< out: previous level */
-{
-	if (wdl_db_return_ != NULL) {
-
-		wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
-	}
-}
-
-/**************************************************************//**
-Log arguments for subsequent use. It makes the call to _db_pargs_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_pargs_(
-	uint		_line_,		/*!< in: current source line number */
-	const char*	keyword)	/*!< in: keyword for current macro */
-{
-	if (wdl_db_pargs_ != NULL) {
-
-		wdl_db_pargs_(_line_, keyword);
-	}
-}
-
-/**************************************************************//**
-Handle print of debug lines. It saves the text into a buffer first,
-then makes the call to _db_doprnt_() in the server. The text is
-truncated to the size of buffer. */
-extern "C" UNIV_INTERN
-void
-_db_doprnt_(
-	const char*	format,		/*!< in: the format string */
-	...)				/*!< in: list of arguments */
-{
-	va_list		argp;
-	char		buffer[512];
-
-	if (wdl_db_doprnt_ != NULL) {
-
-		va_start(argp, format);
-		/* it is ok to ignore the trunction. */
-		_vsnprintf(buffer, sizeof(buffer), format, argp);
-		wdl_db_doprnt_(buffer);
-		va_end(argp);
-	}
-}
-
-/**************************************************************//**
-Dump a string in hex. It makes the call to _db_dump_() in the server. */
-extern "C" UNIV_INTERN
-void
-_db_dump_(
-	uint			_line_,		/*!< in: current source line
-						number */
-	const char*		keyword,	/*!< in: keyword list */
-	const unsigned char*	memory,		/*!< in: memory to dump */
-	size_t			length)		/*!< in: bytes to dump */
-{
-	if (wdl_db_dump_ != NULL) {
-
-		wdl_db_dump_(_line_, keyword, memory, length);
-	}
-}
-
-#endif /* !DBUG_OFF */
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */

=== modified file 'storage/innodb_plugin/include/buf0buf.h'
--- a/storage/innodb_plugin/include/buf0buf.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/buf0buf.h	2009-10-08 13:05:59 +0000
@@ -346,7 +346,7 @@ buf_page_release(
 	mtr_t*		mtr);		/*!< in: mtr */
 /********************************************************************//**
 Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
 the buffer pool. */
 UNIV_INTERN
 void
@@ -707,15 +707,6 @@ buf_page_belongs_to_unzip_LRU(
 /*==========================*/
 	const buf_page_t*	bpage)	/*!< in: pointer to control block */
 	__attribute__((pure));
-/*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return	LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
-	const buf_page_t*	bpage)	/*!< in: control block */
-	__attribute__((pure));
 
 /*********************************************************************//**
 Gets the mutex of a block.
@@ -816,14 +807,14 @@ buf_page_set_old(
 	buf_page_t*	bpage,	/*!< in/out: control block */
 	ibool		old);	/*!< in: old */
 /*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return	TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return	ut_time_ms() at the time of first access, 0 if not accessed */
 UNIV_INLINE
-ibool
+unsigned
 buf_page_is_accessed(
 /*=================*/
 	const buf_page_t*	bpage)	/*!< in: control block */
-	__attribute__((pure));
+	__attribute__((nonnull, pure));
 /*********************************************************************//**
 Flag a block accessed. */
 UNIV_INLINE
@@ -831,7 +822,8 @@ void
 buf_page_set_accessed(
 /*==================*/
 	buf_page_t*	bpage,		/*!< in/out: control block */
-	ibool		accessed);	/*!< in: accessed */
+	ulint		time_ms)	/*!< in: ut_time_ms() */
+	__attribute__((nonnull));
 /*********************************************************************//**
 Gets the buf_block_t handle of a buffered file block if an uncompressed
 page frame exists, or NULL.
@@ -1017,14 +1009,6 @@ buf_block_hash_get(
 /*===============*/
 	ulint	space,	/*!< in: space id */
 	ulint	offset);/*!< in: offset of the page within space */
-/*******************************************************************//**
-Increments the pool clock by one and returns its new value. Remember that
-in the 32 bit version the clock wraps around at 4 billion!
-@return	new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void);
-/*====================*/
 /*********************************************************************//**
 Gets the current length of the free list of buffer blocks.
 @return	length of the free list */
@@ -1064,16 +1048,10 @@ struct buf_page_struct{
 					flushed to disk, this tells the
 					flush_type.
 					@see enum buf_flush */
-	unsigned	accessed:1;	/*!< TRUE if the page has been accessed
-					while in the buffer pool: read-ahead
-					may read in pages which have not been
-					accessed yet; a thread is allowed to
-					read this for heuristic purposes
-					without holding any mutex or latch */
 	unsigned	io_fix:2;	/*!< type of pending I/O operation;
 					also protected by buf_pool_mutex
 					@see enum buf_io_fix */
-	unsigned	buf_fix_count:24;/*!< count of how manyfold this block
+	unsigned	buf_fix_count:25;/*!< count of how manyfold this block
 					is currently bufferfixed */
 	/* @} */
 #endif /* !UNIV_HOTBACKUP */
@@ -1103,7 +1081,16 @@ struct buf_page_struct{
 					- BUF_BLOCK_FILE_PAGE:	flush_list
 					- BUF_BLOCK_ZIP_DIRTY:	flush_list
 					- BUF_BLOCK_ZIP_PAGE:	zip_clean
-					- BUF_BLOCK_ZIP_FREE:	zip_free[] */
+					- BUF_BLOCK_ZIP_FREE:	zip_free[]
+
+					The contents of the list node
+					is undefined if !in_flush_list
+					&& state == BUF_BLOCK_FILE_PAGE,
+					or if state is one of
+					BUF_BLOCK_MEMORY,
+					BUF_BLOCK_REMOVE_HASH or
+					BUF_BLOCK_READY_IN_USE. */
+
 #ifdef UNIV_DEBUG
 	ibool		in_flush_list;	/*!< TRUE if in buf_pool->flush_list;
 					when buf_pool_mutex is free, the
@@ -1143,17 +1130,7 @@ struct buf_page_struct{
 #endif /* UNIV_DEBUG */
 	unsigned	old:1;		/*!< TRUE if the block is in the old
 					blocks in the LRU list */
-	unsigned	LRU_position:31;/*!< value which monotonically
-					decreases (or may stay
-					constant if old==TRUE) toward
-					the end of the LRU list, if
-					buf_pool->ulint_clock has not
-					wrapped around: NOTE that this
-					value can only be used in
-					heuristic algorithms, because
-					of the possibility of a
-					wrap-around! */
-	unsigned	freed_page_clock:32;/*!< the value of
+	unsigned	freed_page_clock:31;/*!< the value of
 					buf_pool->freed_page_clock
 					when this block was the last
 					time put to the head of the
@@ -1161,6 +1138,9 @@ struct buf_page_struct{
 					to read this for heuristic
 					purposes without holding any
 					mutex or latch */
+	unsigned	access_time:32;	/*!< time of first access, or
+					0 if the block was never accessed
+					in the buffer pool */
 	/* @} */
 # ifdef UNIV_DEBUG_FILE_ACCESSES
 	ibool		file_page_was_freed;
@@ -1305,6 +1285,31 @@ Compute the hash fold value for blocks i
 #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
 /* @} */
 
+/** @brief The buffer pool statistics structure. */
+struct buf_pool_stat_struct{
+	ulint	n_page_gets;	/*!< number of page gets performed;
+				also successful searches through
+				the adaptive hash index are
+				counted as page gets; this field
+				is NOT protected by the buffer
+				pool mutex */
+	ulint	n_pages_read;	/*!< number read operations */
+	ulint	n_pages_written;/*!< number write operations */
+	ulint	n_pages_created;/*!< number of pages created
+				in the pool with no read */
+	ulint	n_ra_pages_read;/*!< number of pages read in
+				as part of read ahead */
+	ulint	n_ra_pages_evicted;/*!< number of read ahead
+				pages that are evicted without
+				being accessed */
+	ulint	n_pages_made_young; /*!< number of pages made young, in
+				calls to buf_LRU_make_block_young() */
+	ulint	n_pages_not_made_young; /*!< number of pages not made
+				young because the first access
+				was not long enough ago, in
+				buf_page_peek_if_too_old() */
+};
+
 /** @brief The buffer pool structure.
 
 NOTE! The definition appears here only for other modules of this
@@ -1329,28 +1334,16 @@ struct buf_pool_struct{
 	ulint		n_pend_reads;	/*!< number of pending read operations */
 	ulint		n_pend_unzip;	/*!< number of pending decompressions */
 
-	time_t		last_printout_time; /*!< when buf_print was last time
+	time_t		last_printout_time;
+					/*!< when buf_print_io was last time
 					called */
-	ulint		n_pages_read;	/*!< number read operations */
-	ulint		n_pages_written;/*!< number write operations */
-	ulint		n_pages_created;/*!< number of pages created
-					in the pool with no read */
-	ulint		n_page_gets;	/*!< number of page gets performed;
-					also successful searches through
-					the adaptive hash index are
-					counted as page gets; this field
-					is NOT protected by the buffer
-					pool mutex */
-	ulint		n_page_gets_old;/*!< n_page_gets when buf_print was
-					last time called: used to calculate
-					hit rate */
-	ulint		n_pages_read_old;/*!< n_pages_read when buf_print was
-					last time called */
-	ulint		n_pages_written_old;/*!< number write operations */
-	ulint		n_pages_created_old;/*!< number of pages created in
-					the pool with no read */
+	buf_pool_stat_t	stat;		/*!< current statistics */
+	buf_pool_stat_t	old_stat;	/*!< old statistics */
+
 	/* @} */
+
 	/** @name Page flushing algorithm fields */
+
 	/* @{ */
 
 	UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
@@ -1366,10 +1359,6 @@ struct buf_pool_struct{
 					/*!< this is in the set state
 					when there is no flush batch
 					of the given type running */
-	ulint		ulint_clock;	/*!< a sequence number used to count
-					time. NOTE! This counter wraps
-					around at 4 billion (if ulint ==
-					32 bits)! */
 	ulint		freed_page_clock;/*!< a sequence number used
 					to count the number of buffer
 					blocks removed from the end of
@@ -1393,9 +1382,11 @@ struct buf_pool_struct{
 					block list */
 	UT_LIST_BASE_NODE_T(buf_page_t) LRU;
 					/*!< base node of the LRU list */
-	buf_page_t*	LRU_old;	/*!< pointer to the about 3/8 oldest
-					blocks in the LRU list; NULL if LRU
-					length less than BUF_LRU_OLD_MIN_LEN;
+	buf_page_t*	LRU_old;	/*!< pointer to the about
+					buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+					oldest blocks in the LRU list;
+					NULL if LRU length less than
+					BUF_LRU_OLD_MIN_LEN;
 					NOTE: when LRU_old != NULL, its length
 					should always equal LRU_old_len */
 	ulint		LRU_old_len;	/*!< length of the LRU list from

=== modified file 'storage/innodb_plugin/include/buf0buf.ic'
--- a/storage/innodb_plugin/include/buf0buf.ic	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/buf0buf.ic	2009-10-08 13:05:59 +0000
@@ -72,9 +72,30 @@ buf_page_peek_if_too_old(
 /*=====================*/
 	const buf_page_t*	bpage)	/*!< in: block to make younger */
 {
-	return(buf_pool->freed_page_clock
-	       >= buf_page_get_freed_page_clock(bpage)
-	       + 1 + (buf_pool->curr_size / 4));
+	if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
+		/* If eviction has not started yet, do not update the
+		statistics or move blocks in the LRU list.  This is
+		either the warm-up phase or an in-memory workload. */
+		return(FALSE);
+	} else if (buf_LRU_old_threshold_ms && bpage->old) {
+		unsigned	access_time = buf_page_is_accessed(bpage);
+
+		if (access_time > 0
+		    && (ut_time_ms() - access_time)
+		    >= buf_LRU_old_threshold_ms) {
+			return(TRUE);
+		}
+
+		buf_pool->stat.n_pages_not_made_young++;
+		return(FALSE);
+	} else {
+		/* FIXME: bpage->freed_page_clock is 31 bits */
+		return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
+		       > ((ulint) bpage->freed_page_clock
+			  + (buf_pool->curr_size
+			     * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
+			     / (BUF_LRU_OLD_RATIO_DIV * 4))));
+	}
 }
 
 /*********************************************************************//**
@@ -118,22 +139,6 @@ buf_pool_get_oldest_modification(void)
 
 	return(lsn);
 }
-
-/*******************************************************************//**
-Increments the buf_pool clock by one and returns its new value. Remember
-that in the 32 bit version the clock wraps around at 4 billion!
-@return	new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void)
-/*====================*/
-{
-	ut_ad(buf_pool_mutex_own());
-
-	buf_pool->ulint_clock++;
-
-	return(buf_pool->ulint_clock);
-}
 #endif /* !UNIV_HOTBACKUP */
 
 /*********************************************************************//**
@@ -280,21 +285,6 @@ buf_page_belongs_to_unzip_LRU(
 }
 
 /*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return	LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
-	const buf_page_t*	bpage)	/*!< in: control block */
-{
-	ut_ad(buf_page_in_file(bpage));
-	ut_ad(buf_pool_mutex_own());
-
-	return(bpage->LRU_position);
-}
-
-/*********************************************************************//**
 Gets the mutex of a block.
 @return	pointer to mutex protecting bpage */
 UNIV_INLINE
@@ -487,17 +477,17 @@ buf_page_set_old(
 }
 
 /*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return	TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return	ut_time_ms() at the time of first access, 0 if not accessed */
 UNIV_INLINE
-ibool
+unsigned
 buf_page_is_accessed(
 /*=================*/
 	const buf_page_t*	bpage)	/*!< in: control block */
 {
 	ut_ad(buf_page_in_file(bpage));
 
-	return(bpage->accessed);
+	return(bpage->access_time);
 }
 
 /*********************************************************************//**
@@ -507,12 +497,15 @@ void
 buf_page_set_accessed(
 /*==================*/
 	buf_page_t*	bpage,		/*!< in/out: control block */
-	ibool		accessed)	/*!< in: accessed */
+	ulint		time_ms)	/*!< in: ut_time_ms() */
 {
 	ut_a(buf_page_in_file(bpage));
-	ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+	ut_ad(buf_pool_mutex_own());
 
-	bpage->accessed = accessed;
+	if (!bpage->access_time) {
+		/* Make this the time of the first access. */
+		bpage->access_time = time_ms;
+	}
 }
 
 /*********************************************************************//**

=== modified file 'storage/innodb_plugin/include/buf0lru.h'
--- a/storage/innodb_plugin/include/buf0lru.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/buf0lru.h	2009-10-08 11:28:37 +0000
@@ -69,7 +69,7 @@ These are low-level functions
 #########################################################################*/
 
 /** Minimum LRU list length for which the LRU_old pointer is defined */
-#define BUF_LRU_OLD_MIN_LEN	80
+#define BUF_LRU_OLD_MIN_LEN	512	/* 8 megabytes of 16k pages */
 
 /** Maximum LRU list search length in buf_flush_LRU_recommendation() */
 #define BUF_LRU_FREE_SEARCH_LEN		(5 + 2 * BUF_READ_AHEAD_AREA)
@@ -84,15 +84,6 @@ void
 buf_LRU_invalidate_tablespace(
 /*==========================*/
 	ulint	id);	/*!< in: space id */
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return	the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void);
-/*==========================*/
 /********************************************************************//**
 Insert a compressed block into buf_pool->zip_clean in the LRU order. */
 UNIV_INTERN
@@ -201,6 +192,18 @@ void
 buf_LRU_make_block_old(
 /*===================*/
 	buf_page_t*	bpage);	/*!< in: control block */
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return	updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+	uint	old_pct,/*!< in: Reserve this percentage of
+			the buffer pool for "old" blocks. */
+	ibool	adjust);/*!< in: TRUE=adjust the LRU list;
+			FALSE=just assign buf_LRU_old_ratio
+			during the initialization of InnoDB */
 /********************************************************************//**
 Update the historical stats that we are collecting for LRU eviction
 policy at the end of each interval. */
@@ -227,6 +230,35 @@ buf_LRU_print(void);
 /*===============*/
 #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
 
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks.  Protected by buf_pool_mutex. */
+extern uint	buf_LRU_old_ratio;
+/** The denominator of buf_LRU_old_ratio. */
+#define BUF_LRU_OLD_RATIO_DIV	1024
+/** Maximum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update */
+#define BUF_LRU_OLD_RATIO_MAX	BUF_LRU_OLD_RATIO_DIV
+/** Minimum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update
+The minimum must exceed
+(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
+#define BUF_LRU_OLD_RATIO_MIN	51
+
+#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
+# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
+#endif
+#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
+# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
+#endif
+
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago.  Not protected by any mutex or latch. */
+extern uint	buf_LRU_old_threshold_ms;
+/* @} */
+
 /** @brief Statistics for selecting the LRU list for eviction.
 
 These statistics are not 'of' LRU but 'for' LRU.  We keep count of I/O

=== modified file 'storage/innodb_plugin/include/buf0rea.h'
--- a/storage/innodb_plugin/include/buf0rea.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/buf0rea.h	2009-10-08 11:28:37 +0000
@@ -33,12 +33,10 @@ Created 11/5/1995 Heikki Tuuri
 High-level function which reads a page asynchronously from a file to the
 buffer buf_pool if it is not already there. Sets the io_fix flag and sets
 an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
 UNIV_INTERN
-ulint
+ibool
 buf_read_page(
 /*==========*/
 	ulint	space,	/*!< in: space id */
@@ -48,7 +46,7 @@ buf_read_page(
 Applies linear read-ahead if in the buf_pool the page is a border page of
 a linear read-ahead area and all the pages in the area have been accessed.
 Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
 predecessor of the page, which on the leaf level of a B-tree are the next
 and previous page in the chain of leaves. To know these, the page specified
 in (space, offset) must already be present in the buf_pool. Thus, the

=== modified file 'storage/innodb_plugin/include/buf0types.h'
--- a/storage/innodb_plugin/include/buf0types.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/buf0types.h	2009-10-08 11:28:37 +0000
@@ -34,6 +34,8 @@ typedef	struct buf_block_struct		buf_blo
 typedef struct buf_chunk_struct		buf_chunk_t;
 /** Buffer pool comprising buf_chunk_t */
 typedef	struct buf_pool_struct		buf_pool_t;
+/** Buffer pool statistics struct */
+typedef	struct buf_pool_stat_struct	buf_pool_stat_t;
 
 /** A buffer frame. @see page_t */
 typedef	byte	buf_frame_t;

=== modified file 'storage/innodb_plugin/include/dict0crea.h'
--- a/storage/innodb_plugin/include/dict0crea.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/dict0crea.h	2009-10-08 09:13:16 +0000
@@ -110,7 +110,7 @@ dict_create_or_check_foreign_constraint_
 Adds foreign key definitions to data dictionary tables in the database. We
 look at table->foreign_list, and also generate names to constraints that were
 not named by the user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
 given locally for this table, that is, the number is not global, as in the
 old format constraints < 4.0.18 it used to be.
 @return	error code or DB_SUCCESS */

=== modified file 'storage/innodb_plugin/include/dict0dict.h'
--- a/storage/innodb_plugin/include/dict0dict.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/dict0dict.h	2009-10-08 11:28:37 +0000
@@ -712,7 +712,7 @@ dict_index_find_on_id_low(
 	dulint	id);	/*!< in: index id */
 /**********************************************************************//**
 Adds an index to the dictionary cache.
-@return	DB_SUCCESS or error code */
+@return	DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
 UNIV_INTERN
 ulint
 dict_index_add_to_cache(

=== modified file 'storage/innodb_plugin/include/dict0mem.h'
--- a/storage/innodb_plugin/include/dict0mem.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/dict0mem.h	2009-10-08 10:00:49 +0000
@@ -317,7 +317,7 @@ struct dict_foreign_struct{
 	char*		id;		/*!< id of the constraint as a
 					null-terminated string */
 	unsigned	n_fields:10;	/*!< number of indexes' first fields
-					for which the the foreign key
+					for which the foreign key
 					constraint is defined: we allow the
 					indexes to contain more fields than
 					mentioned in the constraint, as long

=== modified file 'storage/innodb_plugin/include/fsp0fsp.h'
--- a/storage/innodb_plugin/include/fsp0fsp.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/fsp0fsp.h	2009-10-08 10:00:49 +0000
@@ -42,7 +42,7 @@ fsp_init(void);
 /*==========*/
 /**********************************************************************//**
 Gets the current free limit of the system tablespace.  The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
 free list for allocation.  The space above that address is initialized
 to zero.  Sets also the global variable log_fsp_current_free_limit.
 @return	free limit in megabytes */

=== modified file 'storage/innodb_plugin/include/lock0lock.h'
--- a/storage/innodb_plugin/include/lock0lock.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/lock0lock.h	2009-10-08 12:18:19 +0000
@@ -630,6 +630,14 @@ lock_number_of_rows_locked(
 /*=======================*/
 	trx_t*	trx);	/*!< in: transaction */
 /*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+	const trx_t*	trx);		/*!< in: transaction */
+/*******************************************************************//**
 Release all the transaction's autoinc locks. */
 UNIV_INTERN
 void

=== modified file 'storage/innodb_plugin/include/log0log.h'
--- a/storage/innodb_plugin/include/log0log.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/log0log.h	2009-10-08 12:18:19 +0000
@@ -118,10 +118,9 @@ UNIV_INLINE
 ib_uint64_t
 log_reserve_and_write_fast(
 /*=======================*/
-	byte*		str,	/*!< in: string */
+	const void*	str,	/*!< in: string */
 	ulint		len,	/*!< in: string length */
-	ib_uint64_t*	start_lsn,/*!< out: start lsn of the log record */
-	ibool*		success);/*!< out: TRUE if success */
+	ib_uint64_t*	start_lsn);/*!< out: start lsn of the log record */
 /***********************************************************************//**
 Releases the log mutex. */
 UNIV_INLINE
@@ -283,7 +282,7 @@ log_make_checkpoint_at(
 					later lsn, if IB_ULONGLONG_MAX, makes
 					a checkpoint at the latest lsn */
 	ibool		write_always);	/*!< in: the function normally checks if
-					the the new checkpoint would have a
+					the new checkpoint would have a
 					greater lsn than the previous one: if
 					not, then no physical write is done;
 					by setting this parameter TRUE, a

=== modified file 'storage/innodb_plugin/include/log0log.ic'
--- a/storage/innodb_plugin/include/log0log.ic	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/log0log.ic	2009-10-09 12:52:18 +0000
@@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
 #include "mach0data.h"
 #include "mtr0mtr.h"
 
+#ifdef UNIV_LOG_DEBUG
 /******************************************************//**
 Checks by parsing that the catenated log segment for a single mtr is
 consistent. */
@@ -34,11 +35,12 @@ UNIV_INTERN
 ibool
 log_check_log_recs(
 /*===============*/
-	byte*		buf,		/*!< in: pointer to the start of
+	const byte*	buf,		/*!< in: pointer to the start of
 					the log segment in the
 					log_sys->buf log buffer */
 	ulint		len,		/*!< in: segment length in bytes */
 	ib_uint64_t	buf_start_lsn);	/*!< in: buffer start lsn */
+#endif /* UNIV_LOG_DEBUG */
 
 /************************************************************//**
 Gets a log block flush bit.
@@ -305,55 +307,76 @@ UNIV_INLINE
 ib_uint64_t
 log_reserve_and_write_fast(
 /*=======================*/
-	byte*		str,	/*!< in: string */
+	const void*	str,	/*!< in: string */
 	ulint		len,	/*!< in: string length */
-	ib_uint64_t*	start_lsn,/*!< out: start lsn of the log record */
-	ibool*		success)/*!< out: TRUE if success */
+	ib_uint64_t*	start_lsn)/*!< out: start lsn of the log record */
 {
-	log_t*		log	= log_sys;
 	ulint		data_len;
-	ib_uint64_t	lsn;
-
-	*success = TRUE;
-
-	mutex_enter(&(log->mutex));
-
-	data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
+#ifdef UNIV_LOG_LSN_DEBUG
+	/* length of the LSN pseudo-record */
+	ulint		lsn_len = 1
+		+ mach_get_compressed_size(log_sys->lsn >> 32)
+		+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
+#endif /* UNIV_LOG_LSN_DEBUG */
+
+	mutex_enter(&log_sys->mutex);
+
+	data_len = len
+#ifdef UNIV_LOG_LSN_DEBUG
+		+ lsn_len
+#endif /* UNIV_LOG_LSN_DEBUG */
+		+ log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
 
 	if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
 
 		/* The string does not fit within the current log block
 		or the log block would become full */
 
-		*success = FALSE;
-
-		mutex_exit(&(log->mutex));
+		mutex_exit(&log_sys->mutex);
 
 		return(0);
 	}
 
-	*start_lsn = log->lsn;
+	*start_lsn = log_sys->lsn;
+
+#ifdef UNIV_LOG_LSN_DEBUG
+	{
+		/* Write the LSN pseudo-record. */
+		byte* b = &log_sys->buf[log_sys->buf_free];
+		*b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
+		/* Write the LSN in two parts,
+		as a pseudo page number and space id. */
+		b += mach_write_compressed(b, log_sys->lsn >> 32);
+		b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
+		ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
 
-	ut_memcpy(log->buf + log->buf_free, str, len);
+		memcpy(b, str, len);
+		len += lsn_len;
+	}
+#else /* UNIV_LOG_LSN_DEBUG */
+	memcpy(log_sys->buf + log_sys->buf_free, str, len);
+#endif /* UNIV_LOG_LSN_DEBUG */
 
-	log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
+	log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+						     + log_sys->buf_free,
 						     OS_FILE_LOG_BLOCK_SIZE),
 			       data_len);
 #ifdef UNIV_LOG_DEBUG
-	log->old_buf_free = log->buf_free;
-	log->old_lsn = log->lsn;
+	log_sys->old_buf_free = log_sys->buf_free;
+	log_sys->old_lsn = log_sys->lsn;
 #endif
-	log->buf_free += len;
+	log_sys->buf_free += len;
 
-	ut_ad(log->buf_free <= log->buf_size);
+	ut_ad(log_sys->buf_free <= log_sys->buf_size);
 
-	lsn = log->lsn += len;
+	log_sys->lsn += len;
 
 #ifdef UNIV_LOG_DEBUG
-	log_check_log_recs(log->buf + log->old_buf_free,
-			   log->buf_free - log->old_buf_free, log->old_lsn);
+	log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
+			   log_sys->buf_free - log_sys->old_buf_free,
+			   log_sys->old_lsn);
 #endif
-	return(lsn);
+	return(log_sys->lsn);
 }
 
 /***********************************************************************//**

=== modified file 'storage/innodb_plugin/include/log0recv.h'
--- a/storage/innodb_plugin/include/log0recv.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/log0recv.h	2009-10-09 14:13:15 +0000
@@ -433,6 +433,11 @@ are allowed yet: the variable name is mi
 extern ibool		recv_no_ibuf_operations;
 /** TRUE when recv_init_crash_recovery() has been called. */
 extern ibool		recv_needed_recovery;
+#ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+extern ibool		recv_no_log_write;
+#endif /* UNIV_DEBUG */
 
 /** TRUE if buf_page_is_corrupted() should check if the log sequence
 number (FIL_PAGE_LSN) is in the future.  Initially FALSE, and set by

=== modified file 'storage/innodb_plugin/include/mtr0mtr.h'
--- a/storage/innodb_plugin/include/mtr0mtr.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/mtr0mtr.h	2009-10-09 12:52:18 +0000
@@ -106,6 +106,9 @@ For 1 - 8 bytes, the flag value must giv
 #define MLOG_IBUF_BITMAP_INIT	((byte)27)	/*!< initialize an
 						ibuf bitmap page */
 /*#define	MLOG_FULL_PAGE	((byte)28)	full contents of a page */
+#ifdef UNIV_LOG_LSN_DEBUG
+# define MLOG_LSN		((byte)28)	/* current LSN */
+#endif
 #define MLOG_INIT_FILE_PAGE	((byte)29)	/*!< this means that a
 						file page is taken
 						into use and the prior
@@ -118,7 +121,7 @@ For 1 - 8 bytes, the flag value must giv
 #define MLOG_WRITE_STRING	((byte)30)	/*!< write a string to
 						a page */
 #define	MLOG_MULTI_REC_END	((byte)31)	/*!< if a single mtr writes
-						log records for several pages,
+						several log records,
 						this log record ends the
 						sequence of these records */
 #define MLOG_DUMMY_RECORD	((byte)32)	/*!< dummy log record used to

=== modified file 'storage/innodb_plugin/include/os0file.h'
--- a/storage/innodb_plugin/include/os0file.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/os0file.h	2009-10-09 14:02:18 +0000
@@ -157,6 +157,7 @@ log. */
 						to become available again */
 #define	OS_FILE_SHARING_VIOLATION	76
 #define	OS_FILE_ERROR_NOT_SPECIFIED	77
+#define	OS_FILE_INSUFFICIENT_RESOURCE	78
 /* @} */
 
 /** Types for aio operations @{ */

=== modified file 'storage/innodb_plugin/include/os0sync.h'
--- a/storage/innodb_plugin/include/os0sync.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/os0sync.h	2009-10-12 12:00:56 +0000
@@ -285,44 +285,74 @@ os_fast_mutex_free(
 /**********************************************************//**
 Atomic compare-and-swap and increment for InnoDB. */
 
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
+
+#define HAVE_ATOMIC_BUILTINS
+
 /**********************************************************//**
 Returns true if swapped, ptr is pointer to target, old_val is value to
 compare to, new_val is the value to swap in. */
+
 # define os_compare_and_swap(ptr, old_val, new_val) \
 	__sync_bool_compare_and_swap(ptr, old_val, new_val)
+
 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
 	os_compare_and_swap(ptr, old_val, new_val)
+
 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
 	os_compare_and_swap(ptr, old_val, new_val)
-# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
+#  define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
 	os_compare_and_swap(ptr, old_val, new_val)
+#  define INNODB_RW_LOCKS_USE_ATOMICS
+#  define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes and rw_locks use GCC atomic builtins"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+#  define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes use GCC atomic builtins, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+
 /**********************************************************//**
 Returns the resulting value, ptr is pointer to target, amount is the
 amount of increment. */
+
 # define os_atomic_increment(ptr, amount) \
 	__sync_add_and_fetch(ptr, amount)
+
 # define os_atomic_increment_lint(ptr, amount) \
 	os_atomic_increment(ptr, amount)
+
 # define os_atomic_increment_ulint(ptr, amount) \
 	os_atomic_increment(ptr, amount)
+
 /**********************************************************//**
 Returns the old value of *ptr, atomically sets *ptr to new_val */
+
 # define os_atomic_test_and_set_byte(ptr, new_val) \
 	__sync_lock_test_and_set(ptr, new_val)
+
+#elif defined(HAVE_IB_SOLARIS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
 /* If not compiling with GCC or GCC doesn't support the atomic
 intrinsics and running on Solaris >= 10 use Solaris atomics */
-#elif defined(HAVE_SOLARIS_ATOMICS)
+
 #include <atomic.h>
+
 /**********************************************************//**
 Returns true if swapped, ptr is pointer to target, old_val is value to
 compare to, new_val is the value to swap in. */
+
 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
 	(atomic_cas_ulong(ptr, old_val, new_val) == old_val)
+
 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
 	((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-#  if   SIZEOF_PTHREAD_T == 4
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
+#  if SIZEOF_PTHREAD_T == 4
 #   define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
 	((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
 #  elif SIZEOF_PTHREAD_T == 8
@@ -331,21 +361,35 @@ compare to, new_val is the value to swap
 #  else
 #   error "SIZEOF_PTHREAD_T != 4 or 8"
 #  endif /* SIZEOF_PTHREAD_T CHECK */
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+#  define INNODB_RW_LOCKS_USE_ATOMICS
+#  define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes and rw_locks use Solaris atomic functions"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
+#  define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes use Solaris atomic functions, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
 
 /**********************************************************//**
 Returns the resulting value, ptr is pointer to target, amount is the
 amount of increment. */
+
 # define os_atomic_increment_lint(ptr, amount) \
 	atomic_add_long_nv((ulong_t*) ptr, amount)
+
 # define os_atomic_increment_ulint(ptr, amount) \
 	atomic_add_long_nv(ptr, amount)
+
 /**********************************************************//**
 Returns the old value of *ptr, atomically sets *ptr to new_val */
+
 # define os_atomic_test_and_set_byte(ptr, new_val) \
 	atomic_swap_uchar(ptr, new_val)
-/* On Windows, use Windows atomics / interlocked */
+
 #elif defined(HAVE_WINDOWS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/* On Windows, use Windows atomics / interlocked */
 # ifdef _WIN64
 #  define win_cmp_and_xchg InterlockedCompareExchange64
 #  define win_xchg_and_add InterlockedExchangeAdd64
@@ -353,31 +397,46 @@ Returns the old value of *ptr, atomicall
 #  define win_cmp_and_xchg InterlockedCompareExchange
 #  define win_xchg_and_add InterlockedExchangeAdd
 # endif
+
 /**********************************************************//**
 Returns true if swapped, ptr is pointer to target, old_val is value to
 compare to, new_val is the value to swap in. */
+
 # define os_compare_and_swap_ulint(ptr, old_val, new_val) \
 	(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+
 # define os_compare_and_swap_lint(ptr, old_val, new_val) \
 	(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-#  define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+/* windows thread objects can always be passed to windows atomic functions */
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
 	(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes and rw_locks use Windows interlocked functions"
+
 /**********************************************************//**
 Returns the resulting value, ptr is pointer to target, amount is the
 amount of increment. */
+
 # define os_atomic_increment_lint(ptr, amount) \
 	(win_xchg_and_add(ptr, amount) + amount)
+
 # define os_atomic_increment_ulint(ptr, amount) \
 	((ulint) (win_xchg_and_add(ptr, amount) + amount))
+
 /**********************************************************//**
 Returns the old value of *ptr, atomically sets *ptr to new_val.
 InterlockedExchange() operates on LONG, and the LONG will be
 clobbered */
+
 # define os_atomic_test_and_set_byte(ptr, new_val) \
 	((byte) InterlockedExchange(ptr, new_val))
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+
+#else
+# define IB_ATOMICS_STARTUP_MSG \
+	"Mutexes and rw_locks use InnoDB's own implementation"
+#endif
 
 #ifndef UNIV_NONINL
 #include "os0sync.ic"

=== modified file 'storage/innodb_plugin/include/page0page.h'
--- a/storage/innodb_plugin/include/page0page.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/page0page.h	2009-10-09 14:13:15 +0000
@@ -76,8 +76,11 @@ typedef	byte		page_header_t;
 				header which are set in a page create */
 /*----*/
 #define	PAGE_LEVEL	 26	/* level of the node in an index tree; the
-				leaf level is the level 0 */
-#define	PAGE_INDEX_ID	 28	/* index id where the page belongs */
+				leaf level is the level 0.  This field should
+				not be written to after page creation. */
+#define	PAGE_INDEX_ID	 28	/* index id where the page belongs.
+				This field should not be written to after
+				page creation. */
 #define PAGE_BTR_SEG_LEAF 36	/* file segment header for the leaf pages in
 				a B-tree: defined only on the root page of a
 				B-tree, but not in the root of an ibuf tree */

=== modified file 'storage/innodb_plugin/include/page0zip.h'
--- a/storage/innodb_plugin/include/page0zip.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/page0zip.h	2009-10-09 14:13:15 +0000
@@ -127,8 +127,12 @@ page_zip_decompress(
 /*================*/
 	page_zip_des_t*	page_zip,/*!< in: data, ssize;
 				out: m_start, m_end, m_nonempty, n_blobs */
-	page_t*		page)	/*!< out: uncompressed page, may be trashed */
-	__attribute__((nonnull));
+	page_t*		page,	/*!< out: uncompressed page, may be trashed */
+	ibool		all)	/*!< in: TRUE=decompress the whole page;
+				FALSE=verify but do not copy some
+				page header fields that should not change
+				after page creation */
+	__attribute__((nonnull(1,2)));
 
 #ifdef UNIV_DEBUG
 /**********************************************************************//**
@@ -385,8 +389,8 @@ IMPORTANT: if page_zip_reorganize() is i
 non-clustered index, the caller must update the insert buffer free
 bits in the same mini-transaction in such a way that the modification
 will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
 UNIV_INTERN
 ibool
 page_zip_reorganize(

=== modified file 'storage/innodb_plugin/include/rem0cmp.h'
--- a/storage/innodb_plugin/include/rem0cmp.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/rem0cmp.h	2009-10-08 10:00:49 +0000
@@ -89,7 +89,7 @@ cmp_dfield_dfield(
 /*************************************************************//**
 This function is used to compare a data tuple to a physical record.
 Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
 have either m >= n fields, or it must differ from dtuple in some of
 the m fields rec has. If rec has an externally stored field we do not
 compare it but return with value 0 if such a comparison should be

=== modified file 'storage/innodb_plugin/include/rem0rec.ic'
--- a/storage/innodb_plugin/include/rem0rec.ic	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/rem0rec.ic	2009-10-08 10:00:49 +0000
@@ -65,7 +65,7 @@ most significant bytes and bits are writ
 				   - offset_of_this_record) mod 64Ki,
 				  where mod is the modulo as a non-negative
 				  number;
-				  we can calculate the the offset of the next
+				  we can calculate the offset of the next
 				  record with the formula:
 				  relative_offset + offset_of_this_record
 				  mod UNIV_PAGE_SIZE

=== modified file 'storage/innodb_plugin/include/row0ins.h'
--- a/storage/innodb_plugin/include/row0ins.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/row0ins.h	2009-10-09 14:13:15 +0000
@@ -45,7 +45,7 @@ row_ins_check_foreign_constraint(
 /*=============================*/
 	ibool		check_ref,/*!< in: TRUE If we want to check that
 				the referenced table is ok, FALSE if we
-				want to to check the foreign key table */
+				want to check the foreign key table */
 	dict_foreign_t*	foreign,/*!< in: foreign constraint; NOTE that the
 				tables mentioned in it must be in the
 				dictionary cache if they exist at all */

=== modified file 'storage/innodb_plugin/include/row0mysql.h'
--- a/storage/innodb_plugin/include/row0mysql.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/row0mysql.h	2009-10-08 12:18:19 +0000
@@ -177,7 +177,9 @@ row_update_prebuilt_trx(
 					in MySQL handle */
 	trx_t*		trx);		/*!< in: transaction handle */
 /*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
 UNIV_INTERN
 void
 row_unlock_table_autoinc_for_mysql(

=== modified file 'storage/innodb_plugin/include/srv0srv.h'
--- a/storage/innodb_plugin/include/srv0srv.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/srv0srv.h	2009-10-08 11:28:37 +0000
@@ -315,10 +315,6 @@ extern ulint srv_buf_pool_flushed;
 /** Number of buffer pool reads that led to the
 reading of a disk page */
 extern ulint srv_buf_pool_reads;
-/** Number of sequential read-aheads */
-extern ulint srv_read_ahead_seq;
-/** Number of random read-aheads */
-extern ulint srv_read_ahead_rnd;
 
 /** Status variables to be passed to MySQL */
 typedef struct export_var_struct export_struc;
@@ -605,13 +601,13 @@ struct export_var_struct{
 #ifdef UNIV_DEBUG
 	ulint innodb_buffer_pool_pages_latched;	/*!< Latched pages */
 #endif /* UNIV_DEBUG */
-	ulint innodb_buffer_pool_read_requests;	/*!< buf_pool->n_page_gets */
+	ulint innodb_buffer_pool_read_requests;	/*!< buf_pool->stat.n_page_gets */
 	ulint innodb_buffer_pool_reads;		/*!< srv_buf_pool_reads */
 	ulint innodb_buffer_pool_wait_free;	/*!< srv_buf_pool_wait_free */
 	ulint innodb_buffer_pool_pages_flushed;	/*!< srv_buf_pool_flushed */
 	ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
-	ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
-	ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
+	ulint innodb_buffer_pool_read_ahead;	/*!< srv_read_ahead */
+	ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
 	ulint innodb_dblwr_pages_written;	/*!< srv_dblwr_pages_written */
 	ulint innodb_dblwr_writes;		/*!< srv_dblwr_writes */
 	ibool innodb_have_atomic_builtins;	/*!< HAVE_ATOMIC_BUILTINS */
@@ -623,9 +619,9 @@ struct export_var_struct{
 	ulint innodb_os_log_pending_writes;	/*!< srv_os_log_pending_writes */
 	ulint innodb_os_log_pending_fsyncs;	/*!< fil_n_pending_log_flushes */
 	ulint innodb_page_size;			/*!< UNIV_PAGE_SIZE */
-	ulint innodb_pages_created;		/*!< buf_pool->n_pages_created */
-	ulint innodb_pages_read;		/*!< buf_pool->n_pages_read */
-	ulint innodb_pages_written;		/*!< buf_pool->n_pages_written */
+	ulint innodb_pages_created;		/*!< buf_pool->stat.n_pages_created */
+	ulint innodb_pages_read;		/*!< buf_pool->stat.n_pages_read */
+	ulint innodb_pages_written;		/*!< buf_pool->stat.n_pages_written */
 	ulint innodb_row_lock_waits;		/*!< srv_n_lock_wait_count */
 	ulint innodb_row_lock_current_waits;	/*!< srv_n_lock_wait_current_count */
 	ib_int64_t innodb_row_lock_time;	/*!< srv_n_lock_wait_time

=== modified file 'storage/innodb_plugin/include/trx0rec.h'
--- a/storage/innodb_plugin/include/trx0rec.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0rec.h	2009-10-08 10:00:49 +0000
@@ -44,8 +44,8 @@ UNIV_INLINE
 trx_undo_rec_t*
 trx_undo_rec_copy(
 /*==============*/
-	trx_undo_rec_t*	undo_rec,	/*!< in: undo log record */
-	mem_heap_t*	heap);		/*!< in: heap where copied */
+	const trx_undo_rec_t*	undo_rec,	/*!< in: undo log record */
+	mem_heap_t*		heap);		/*!< in: heap where copied */
 /**********************************************************************//**
 Reads the undo log record type.
 @return	record type */

=== modified file 'storage/innodb_plugin/include/trx0rec.ic'
--- a/storage/innodb_plugin/include/trx0rec.ic	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0rec.ic	2009-10-08 10:00:49 +0000
@@ -100,8 +100,8 @@ UNIV_INLINE
 trx_undo_rec_t*
 trx_undo_rec_copy(
 /*==============*/
-	trx_undo_rec_t*	undo_rec,	/*!< in: undo log record */
-	mem_heap_t*	heap)		/*!< in: heap where copied */
+	const trx_undo_rec_t*	undo_rec,	/*!< in: undo log record */
+	mem_heap_t*		heap)		/*!< in: heap where copied */
 {
 	ulint		len;
 

=== modified file 'storage/innodb_plugin/include/trx0roll.h'
--- a/storage/innodb_plugin/include/trx0roll.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/trx0roll.h	2009-10-08 13:05:59 +0000
@@ -133,6 +133,17 @@ trx_rollback(
 Rollback or clean up any incomplete transactions which were
 encountered in crash recovery.  If the transaction already was
 committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back. */
+UNIV_INTERN
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+	ibool	all);	/*!< in: FALSE=roll back dictionary transactions;
+			TRUE=roll back all non-PREPARED transactions */
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery.  If the transaction already was
+committed, then we clean up a possible insert undo log. If the
 transaction was not yet committed, then we roll it back.
 Note: this is done in a background thread.
 @return	a dummy parameter */
@@ -208,9 +219,9 @@ int
 trx_general_rollback_for_mysql(
 /*===========================*/
 	trx_t*		trx,	/*!< in: transaction handle */
-	ibool		partial,/*!< in: TRUE if partial rollback requested */
 	trx_savept_t*	savept);/*!< in: pointer to savepoint undo number, if
-				partial rollback requested */
+				partial rollback requested, or NULL for
+				complete rollback */
 /*******************************************************************//**
 Rolls back a transaction back to a named savepoint. Modifications after the
 savepoint are undone but InnoDB does NOT release the corresponding locks

=== modified file 'storage/innodb_plugin/include/trx0sys.ic'
--- a/storage/innodb_plugin/include/trx0sys.ic	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/trx0sys.ic	2009-10-08 10:00:49 +0000
@@ -34,11 +34,11 @@ typedef byte	trx_sysf_rseg_t;
 
 /* Rollback segment specification slot offsets */
 /*-------------------------------------------------------------*/
-#define	TRX_SYS_RSEG_SPACE	0	/* space where the the segment
+#define	TRX_SYS_RSEG_SPACE	0	/* space where the segment
 					header is placed; starting with
 					MySQL/InnoDB 5.1.7, this is
 					UNIV_UNDEFINED if the slot is unused */
-#define	TRX_SYS_RSEG_PAGE_NO	4	/*  page number where the the segment
+#define	TRX_SYS_RSEG_PAGE_NO	4	/*  page number where the segment
 					header is placed; this is FIL_NULL
 					if the slot is unused */
 /*-------------------------------------------------------------*/

=== modified file 'storage/innodb_plugin/include/trx0trx.h'
--- a/storage/innodb_plugin/include/trx0trx.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/trx0trx.h	2009-10-08 13:05:59 +0000
@@ -179,7 +179,7 @@ trx_commit_off_kernel(
 /****************************************************************//**
 Cleans up a transaction at database startup. The cleanup is needed if
 the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
 UNIV_INTERN
 void
 trx_cleanup_at_db_startup(
@@ -360,7 +360,7 @@ enum trx_dict_op {
 	operation modes in crash recovery. */
 	TRX_DICT_OP_TABLE = 1,
 	/** The transaction is creating or dropping an index in an
-	existing table.  In crash recovery, the the data dictionary
+	existing table.  In crash recovery, the data dictionary
 	must be locked, but the table must not be dropped. */
 	TRX_DICT_OP_INDEX = 2
 };

=== modified file 'storage/innodb_plugin/include/univ.i'
--- a/storage/innodb_plugin/include/univ.i	2009-08-14 15:18:52 +0000
+++ b/storage/innodb_plugin/include/univ.i	2009-10-12 12:00:56 +0000
@@ -46,11 +46,11 @@ Created 1/20/1994 Heikki Tuuri
 
 #define INNODB_VERSION_MAJOR	1
 #define INNODB_VERSION_MINOR	0
-#define INNODB_VERSION_BUGFIX	4
+#define INNODB_VERSION_BUGFIX	5
 
 /* The following is the InnoDB version as shown in
 SELECT plugin_version FROM information_schema.plugins;
-calculated in in make_version_string() in sql/sql_show.cc like this:
+calculated in make_version_string() in sql/sql_show.cc like this:
 "version >> 8" . "version & 0xff"
 because the version is shown with only one dot, we skip the last
 component, i.e. we show M.N.P as M.N */
@@ -78,17 +78,25 @@ the virtual method table (vtable) in GCC
 # define ha_innobase ha_innodb
 #endif /* MYSQL_DYNAMIC_PLUGIN */
 
+/* if any of the following macros is defined at this point this means
+that the code from the "right" plug.in was executed and we do not
+need to include ut0auxconf.h which would either define the same macros
+or will be empty */
+#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
+ && !defined(HAVE_IB_SOLARIS_ATOMICS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
+ && !defined(SIZEOF_PTHREAD_T) \
+ && !defined(HAVE_IB_PAUSE_INSTRUCTION)
+# include "ut0auxconf.h"
+#endif
+
 #if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
 # undef __WIN__
 # define __WIN__
 
 # include <windows.h>
 
-# if defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-#  define HAVE_ATOMIC_BUILTINS
-# endif /* HAVE_WINDOWS_ATOMICS */
-
 # ifdef _NT_
 #  define __NT__
 # endif
@@ -111,45 +119,17 @@ if we are compiling on Windows. */
 #  include <sys/mman.h> /* mmap() for os0proc.c */
 # endif
 
-# undef PACKAGE
-# undef VERSION
-
 /* Include the header file generated by GNU autoconf */
 # ifndef __WIN__
-#ifndef UNIV_HOTBACKUP
-# include "config.h"
-#endif /* UNIV_HOTBACKUP */
+#  ifndef UNIV_HOTBACKUP
+#   include "config.h"
+#  endif /* UNIV_HOTBACKUP */
 # endif
 
 # ifdef HAVE_SCHED_H
 #  include <sched.h>
 # endif
 
-# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \
-     || defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-#  define HAVE_ATOMIC_BUILTINS
-# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS)
-	|| (HAVE_WINDOWS_ATOMICS) */
-
-/* For InnoDB rw_locks to work with atomics we need the thread_id
-to be no more than machine word wide. The following enables using
-atomics for InnoDB rw_locks where these conditions are met. */
-#ifdef HAVE_ATOMIC_BUILTINS
-/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
-the code from plug.in has defined it and we do not need to include
-ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
-be empty */
-# ifndef HAVE_ATOMIC_PTHREAD_T
-#  include "ut0auxconf.h"
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-/* now HAVE_ATOMIC_PTHREAD_T is eventually defined either by plug.in or
-from Makefile.in->ut0auxconf.h */
-# ifdef HAVE_ATOMIC_PTHREAD_T
-#  define INNODB_RW_LOCKS_USE_ATOMICS
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-#endif /* HAVE_ATOMIC_BUILTINS */
-
 /* We only try to do explicit inlining of functions with gcc and
 Sun Studio */
 
@@ -196,12 +176,18 @@ command. Not tested on Windows. */
 						debugging without UNIV_DEBUG */
 #define UNIV_DEBUG				/* Enable ut_ad() assertions
 						and disable UNIV_INLINE */
+#define UNIV_DEBUG_LOCK_VALIDATE		/* Enable
+						ut_ad(lock_rec_validate_page())
+						assertions. */
 #define UNIV_DEBUG_FILE_ACCESSES		/* Debug .ibd file access
 						(field file_page_was_freed
 						in buf_page_t) */
 #define UNIV_LRU_DEBUG				/* debug the buffer pool LRU */
 #define UNIV_HASH_DEBUG				/* debug HASH_ macros */
 #define UNIV_LIST_DEBUG				/* debug UT_LIST_ macros */
+#define UNIV_LOG_LSN_DEBUG			/* write LSN to the redo log;
+this will break redo log file compatibility, but it may be useful when
+debugging redo log application problems. */
 #define UNIV_MEM_DEBUG				/* detect memory leaks etc */
 #define UNIV_IBUF_DEBUG				/* debug the insert buffer */
 #define UNIV_IBUF_COUNT_DEBUG			/* debug the insert buffer;
@@ -409,7 +395,8 @@ it is read. */
 it is read or written. */
 # define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
 /* Sun Studio includes sun_prefetch.h as of version 5.9 */
-#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
+#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \
+       || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
 # include <sun_prefetch.h>
 #if __SUNPRO_C >= 0x550
 # undef UNIV_INTERN

=== modified file 'storage/innodb_plugin/include/ut0auxconf.h'
--- a/storage/innodb_plugin/include/ut0auxconf.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/ut0auxconf.h	2009-10-09 12:19:13 +0000
@@ -1,14 +1,14 @@
 /* Do not remove this file even though it is empty.
 This file is included in univ.i and will cause compilation failure
 if not present.
-A custom check has been added in the generated
+A custom checks have been added in the generated
 storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
-source archive. This check tries to compile a test program and if
-successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
-This is a hack that has been developed in order to check for pthread_t
-atomicity without the need to regenerate the ./configure script that is
+source archive. These checks eventually define some macros and put
+them in this file.
+This is a hack that has been developed in order to deploy new compile
+time checks without the need to regenerate the ./configure script that is
 distributed in the MySQL 5.1 official source archives.
 If by any chance Makefile.in and ./configure are regenerated and thus
-the hack from Makefile.in wiped away then the "real" check from plug.in
+the hack from Makefile.in wiped away then the "real" checks from plug.in
 will take over.
 */

=== modified file 'storage/innodb_plugin/include/ut0byte.h'
--- a/storage/innodb_plugin/include/ut0byte.h	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/ut0byte.h	2009-10-08 12:18:19 +0000
@@ -219,8 +219,8 @@ UNIV_INLINE
 void*
 ut_align(
 /*=====*/
-	void*	ptr,		/*!< in: pointer */
-	ulint	align_no);	/*!< in: align by this number */
+	const void*	ptr,		/*!< in: pointer */
+	ulint		align_no);	/*!< in: align by this number */
 /*********************************************************//**
 The following function rounds down a pointer to the nearest
 aligned address.

=== modified file 'storage/innodb_plugin/include/ut0byte.ic'
--- a/storage/innodb_plugin/include/ut0byte.ic	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/include/ut0byte.ic	2009-10-08 12:18:19 +0000
@@ -319,8 +319,8 @@ UNIV_INLINE
 void*
 ut_align(
 /*=====*/
-	void*	ptr,		/*!< in: pointer */
-	ulint	align_no)	/*!< in: align by this number */
+	const void*	ptr,		/*!< in: pointer */
+	ulint		align_no)	/*!< in: align by this number */
 {
 	ut_ad(align_no > 0);
 	ut_ad(((align_no - 1) & align_no) == 0);

=== modified file 'storage/innodb_plugin/include/ut0ut.h'
--- a/storage/innodb_plugin/include/ut0ut.h	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/include/ut0ut.h	2009-10-12 12:00:56 +0000
@@ -34,6 +34,11 @@ Created 1/20/1994 Heikki Tuuri
 #define ut0ut_h
 
 #include "univ.i"
+
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#endif /* UNIV_HOTBACKUP */
+
 #include <time.h>
 #ifndef MYSQL_SERVER
 #include <ctype.h>
@@ -47,7 +52,8 @@ Created 1/20/1994 Heikki Tuuri
 /** Time stamp */
 typedef time_t	ib_time_t;
 
-#if defined(IB_HAVE_PAUSE_INSTRUCTION)
+#ifndef UNIV_HOTBACKUP
+#if defined(HAVE_IB_PAUSE_INSTRUCTION)
 #  ifdef WIN32
      /* In the Win32 API, the x86 PAUSE instruction is executed by calling
      the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
@@ -84,6 +90,7 @@ do {								\
 		os_thread_sleep(2000 /* 2 ms */);		\
 	}							\
 } while (0)
+#endif /* !UNIV_HOTBACKUP */
 
 /********************************************************//**
 Gets the high 32 bits in a ulint. That is makes a shift >> 32,
@@ -216,6 +223,7 @@ UNIV_INTERN
 ib_time_t
 ut_time(void);
 /*=========*/
+#ifndef UNIV_HOTBACKUP
 /**********************************************************//**
 Returns system time.
 Upon successful completion, the value 0 is returned; otherwise the
@@ -239,6 +247,16 @@ ullint
 ut_time_us(
 /*=======*/
 	ullint*	tloc);	/*!< out: us since epoch, if non-NULL */
+/**********************************************************//**
+Returns the number of milliseconds since some epoch.  The
+value may wrap around.  It should only be used for heuristic
+purposes.
+@return	ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void);
+/*============*/
+#endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************//**
 Returns the difference of two times in seconds.

=== modified file 'storage/innodb_plugin/lock/lock0lock.c'
--- a/storage/innodb_plugin/lock/lock0lock.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/lock/lock0lock.c	2009-10-09 14:13:15 +0000
@@ -214,7 +214,7 @@ a waiting s-lock request on the next rec
 by a read cursor moving in the ascending order in the index, we cannot
 do the insert immediately, because when we finally commit our transaction,
 the read cursor should see also the new inserted record. So we should
-move the read cursor backward from the the next record for it to pass over
+move the read cursor backward from the next record for it to pass over
 the new inserted record. This move backward may be too cumbersome to
 implement. If we in this situation just enqueue a second x-lock request
 for our transaction on the next record, then the deadlock mechanism
@@ -360,10 +360,9 @@ ibool
 lock_rec_validate_page(
 /*===================*/
 	ulint	space,	/*!< in: space id */
+	ulint	zip_size,/*!< in: compressed page size in bytes
+			or 0 for uncompressed pages */
 	ulint	page_no);/*!< in: page number */
-
-/* Define the following in order to enable lock_rec_validate_page() checks. */
-# undef UNIV_DEBUG_LOCK_VALIDATE
 #endif /* UNIV_DEBUG */
 
 /* The lock system */
@@ -2622,6 +2621,7 @@ lock_move_reorganize_page(
 
 #ifdef UNIV_DEBUG_LOCK_VALIDATE
 	ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+				     buf_block_get_zip_size(block),
 				     buf_block_get_page_no(block)));
 #endif
 }
@@ -2711,8 +2711,10 @@ lock_move_rec_list_end(
 
 #ifdef UNIV_DEBUG_LOCK_VALIDATE
 	ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+				     buf_block_get_zip_size(block),
 				     buf_block_get_page_no(block)));
 	ut_ad(lock_rec_validate_page(buf_block_get_space(new_block),
+				     buf_block_get_zip_size(block),
 				     buf_block_get_page_no(new_block)));
 #endif
 }
@@ -2822,6 +2824,7 @@ lock_move_rec_list_start(
 
 #ifdef UNIV_DEBUG_LOCK_VALIDATE
 	ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+				     buf_block_get_zip_size(block),
 				     buf_block_get_page_no(block)));
 #endif
 }
@@ -3574,7 +3577,8 @@ lock_table_remove_low(
 		and lock_grant()). Therefore it can be empty and we
 		need to check for that. */
 
-		if (!ib_vector_is_empty(trx->autoinc_locks)) {
+		if (!lock_get_wait(lock)
+		    && !ib_vector_is_empty(trx->autoinc_locks)) {
 			lock_t*	autoinc_lock;
 
 			autoinc_lock = ib_vector_pop(trx->autoinc_locks);
@@ -3647,8 +3651,10 @@ lock_table_enqueue_waiting(
 
 	if (lock_deadlock_occurs(lock, trx)) {
 
-		lock_reset_lock_and_trx_wait(lock);
+		/* The order here is important, we don't want to
+		lose the state of the lock before calling remove. */
 		lock_table_remove_low(lock);
+		lock_reset_lock_and_trx_wait(lock);
 
 		return(DB_DEADLOCK);
 	}
@@ -4627,6 +4633,10 @@ lock_rec_queue_validate(
 		next function call: we have to release lock table mutex
 		to obey the latching order */
 
+		/* If this thread is holding the file space latch
+		(fil_space_t::latch), the following check WILL break
+		latching order and may cause a deadlock of threads. */
+
 		impl_trx = lock_sec_rec_some_has_impl_off_kernel(
 			rec, index, offsets);
 
@@ -4684,6 +4694,8 @@ ibool
 lock_rec_validate_page(
 /*===================*/
 	ulint	space,	/*!< in: space id */
+	ulint	zip_size,/*!< in: compressed page size in bytes
+			or 0 for uncompressed pages */
 	ulint	page_no)/*!< in: page number */
 {
 	dict_index_t*	index;
@@ -4694,7 +4706,6 @@ lock_rec_validate_page(
 	ulint		nth_lock	= 0;
 	ulint		nth_bit		= 0;
 	ulint		i;
-	ulint		zip_size;
 	mtr_t		mtr;
 	mem_heap_t*	heap		= NULL;
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4705,7 +4716,6 @@ lock_rec_validate_page(
 
 	mtr_start(&mtr);
 
-	zip_size = fil_space_get_zip_size(space);
 	ut_ad(zip_size != ULINT_UNDEFINED);
 	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
 	buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
@@ -4750,6 +4760,11 @@ loop:
 
 			lock_mutex_exit_kernel();
 
+			/* If this thread is holding the file space
+			latch (fil_space_t::latch), the following
+			check WILL break the latching order and may
+			cause a deadlock of threads. */
+
 			lock_rec_queue_validate(block, rec, index, offsets);
 
 			lock_mutex_enter_kernel();
@@ -4840,7 +4855,9 @@ lock_validate(void)
 
 			lock_mutex_exit_kernel();
 
-			lock_rec_validate_page(space, page_no);
+			lock_rec_validate_page(space,
+					       fil_space_get_zip_size(space),
+					       page_no);
 
 			lock_mutex_enter_kernel();
 
@@ -5364,6 +5381,20 @@ lock_release_autoinc_last_lock(
 }
 
 /*******************************************************************//**
+Check if a transaction holds any autoinc locks. 
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+	const trx_t*	trx)		/*!< in: transaction */
+{
+	ut_a(trx->autoinc_locks != NULL);
+
+	return(!ib_vector_is_empty(trx->autoinc_locks));
+}
+
+/*******************************************************************//**
 Release all the transaction's autoinc locks. */
 UNIV_INTERN
 void

=== modified file 'storage/innodb_plugin/log/log0log.c'
--- a/storage/innodb_plugin/log/log0log.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/log/log0log.c	2009-10-09 14:13:15 +0000
@@ -241,6 +241,7 @@ log_reserve_and_open(
 	ut_a(len < log->buf_size / 2);
 loop:
 	mutex_enter(&(log->mutex));
+	ut_ad(!recv_no_log_write);
 
 	/* Calculate an upper limit for the space the string may take in the
 	log buffer */
@@ -309,6 +310,7 @@ log_write_low(
 
 	ut_ad(mutex_own(&(log->mutex)));
 part_loop:
+	ut_ad(!recv_no_log_write);
 	/* Calculate a part length */
 
 	data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;
@@ -377,6 +379,7 @@ log_close(void)
 	ib_uint64_t	checkpoint_age;
 
 	ut_ad(mutex_own(&(log->mutex)));
+	ut_ad(!recv_no_log_write);
 
 	lsn = log->lsn;
 
@@ -668,8 +671,6 @@ log_calc_max_ages(void)
 	ulint		archive_margin;
 	ulint		smallest_archive_margin;
 
-	ut_ad(!mutex_own(&(log_sys->mutex)));
-
 	mutex_enter(&(log_sys->mutex));
 
 	group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -1117,6 +1118,7 @@ log_io_complete(
 	}
 
 	mutex_enter(&(log_sys->mutex));
+	ut_ad(!recv_no_log_write);
 
 	ut_a(group->n_pending_writes > 0);
 	ut_a(log_sys->n_pending_writes > 0);
@@ -1148,6 +1150,7 @@ log_group_file_header_flush(
 	ulint	dest_offset;
 
 	ut_ad(mutex_own(&(log_sys->mutex)));
+	ut_ad(!recv_no_log_write);
 	ut_a(nth_file < group->n_files);
 
 	buf = *(group->file_header_bufs + nth_file);
@@ -1219,6 +1222,7 @@ log_group_write_buf(
 	ulint	i;
 
 	ut_ad(mutex_own(&(log_sys->mutex)));
+	ut_ad(!recv_no_log_write);
 	ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
 	ut_a(((ulint) start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
 
@@ -1361,6 +1365,7 @@ loop:
 #endif
 
 	mutex_enter(&(log_sys->mutex));
+	ut_ad(!recv_no_log_write);
 
 	if (flush_to_disk
 	    && log_sys->flushed_to_disk_lsn >= lsn) {
@@ -1974,6 +1979,7 @@ log_checkpoint(
 
 	mutex_enter(&(log_sys->mutex));
 
+	ut_ad(!recv_no_log_write);
 	oldest_lsn = log_buf_pool_get_oldest_modification();
 
 	mutex_exit(&(log_sys->mutex));
@@ -2047,7 +2053,7 @@ log_make_checkpoint_at(
 					later lsn, if IB_ULONGLONG_MAX, makes
 					a checkpoint at the latest lsn */
 	ibool		write_always)	/*!< in: the function normally checks if
-					the the new checkpoint would have a
+					the new checkpoint would have a
 					greater lsn than the previous one: if
 					not, then no physical write is done;
 					by setting this parameter TRUE, a
@@ -2086,6 +2092,7 @@ loop:
 	do_checkpoint = FALSE;
 
 	mutex_enter(&(log->mutex));
+	ut_ad(!recv_no_log_write);
 
 	if (log->check_flush_or_checkpoint == FALSE) {
 		mutex_exit(&(log->mutex));
@@ -3035,6 +3042,7 @@ loop:
 #endif /* UNIV_LOG_ARCHIVE */
 
 	mutex_enter(&(log_sys->mutex));
+	ut_ad(!recv_no_log_write);
 
 	if (log_sys->check_flush_or_checkpoint) {
 
@@ -3234,6 +3242,7 @@ loop:
 	ut_a(lsn == log_sys->lsn);
 }
 
+#ifdef UNIV_LOG_DEBUG
 /******************************************************//**
 Checks by parsing that the catenated log segment for a single mtr is
 consistent. */
@@ -3241,7 +3250,7 @@ UNIV_INTERN
 ibool
 log_check_log_recs(
 /*===============*/
-	byte*		buf,		/*!< in: pointer to the start of
+	const byte*	buf,		/*!< in: pointer to the start of
 					the log segment in the
 					log_sys->buf log buffer */
 	ulint		len,		/*!< in: segment length in bytes */
@@ -3249,8 +3258,8 @@ log_check_log_recs(
 {
 	ib_uint64_t	contiguous_lsn;
 	ib_uint64_t	scanned_lsn;
-	byte*		start;
-	byte*		end;
+	const byte*	start;
+	const byte*	end;
 	byte*		buf1;
 	byte*		scan_buf;
 
@@ -3283,6 +3292,7 @@ log_check_log_recs(
 
 	return(TRUE);
 }
+#endif /* UNIV_LOG_DEBUG */
 
 /******************************************************//**
 Peeks the current lsn.

=== modified file 'storage/innodb_plugin/log/log0recv.c'
--- a/storage/innodb_plugin/log/log0recv.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/log/log0recv.c	2009-10-09 14:13:15 +0000
@@ -78,6 +78,11 @@ UNIV_INTERN ibool	recv_recovery_from_bac
 #ifndef UNIV_HOTBACKUP
 /** TRUE when recv_init_crash_recovery() has been called. */
 UNIV_INTERN ibool	recv_needed_recovery = FALSE;
+# ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+UNIV_INTERN ibool	recv_no_log_write = FALSE;
+# endif /* UNIV_DEBUG */
 
 /** TRUE if buf_page_is_corrupted() should check if the log sequence
 number (FIL_PAGE_LSN) is in the future.  Initially FALSE, and set by
@@ -853,6 +858,11 @@ recv_parse_or_apply_log_rec_body(
 	}
 
 	switch (type) {
+#ifdef UNIV_LOG_LSN_DEBUG
+	case MLOG_LSN:
+		/* The LSN is checked in recv_parse_log_rec(). */
+		break;
+#endif /* UNIV_LOG_LSN_DEBUG */
 	case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
 #ifdef UNIV_DEBUG
 		if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
@@ -1269,7 +1279,7 @@ recv_add_to_hash_table(
 					   sizeof(recv_data_t) + len);
 		*prev_field = recv_data;
 
-		ut_memcpy(((byte*)recv_data) + sizeof(recv_data_t), body, len);
+		memcpy(recv_data + 1, body, len);
 
 		prev_field = &(recv_data->next);
 
@@ -1327,6 +1337,7 @@ recv_recover_page_func(
 	buf_block_t*	block)	/*!< in/out: buffer block */
 {
 	page_t*		page;
+	page_zip_des_t*	page_zip;
 	recv_addr_t*	recv_addr;
 	recv_t*		recv;
 	byte*		buf;
@@ -1376,6 +1387,7 @@ recv_recover_page_func(
 	mtr_set_log_mode(&mtr, MTR_LOG_NONE);
 
 	page = block->frame;
+	page_zip = buf_block_get_page_zip(block);
 
 #ifndef UNIV_HOTBACKUP
 	if (just_read_in) {
@@ -1436,13 +1448,19 @@ recv_recover_page_func(
 		if (recv->type == MLOG_INIT_FILE_PAGE) {
 			page_lsn = page_newest_lsn;
 
-			mach_write_ull(page + UNIV_PAGE_SIZE
-				       - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
-			mach_write_ull(page + FIL_PAGE_LSN, 0);
+			memset(FIL_PAGE_LSN + page, 0, 8);
+			memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM
+			       + page, 0, 8);
+
+			if (page_zip) {
+				memset(FIL_PAGE_LSN + page_zip->data, 0, 8);
+			}
 		}
 
 		if (recv->start_lsn >= page_lsn) {
 
+			ib_uint64_t	end_lsn;
+
 			if (!modification_to_page) {
 
 				modification_to_page = TRUE;
@@ -1464,11 +1482,17 @@ recv_recover_page_func(
 			recv_parse_or_apply_log_rec_body(recv->type, buf,
 							 buf + recv->len,
 							 block, &mtr);
-			mach_write_ull(page + UNIV_PAGE_SIZE
-				       - FIL_PAGE_END_LSN_OLD_CHKSUM,
-				       recv->start_lsn + recv->len);
-			mach_write_ull(page + FIL_PAGE_LSN,
-				       recv->start_lsn + recv->len);
+
+			end_lsn = recv->start_lsn + recv->len;
+			mach_write_ull(FIL_PAGE_LSN + page, end_lsn);
+			mach_write_ull(UNIV_PAGE_SIZE
+				       - FIL_PAGE_END_LSN_OLD_CHKSUM
+				       + page, end_lsn);
+
+			if (page_zip) {
+				mach_write_ull(FIL_PAGE_LSN
+					       + page_zip->data, end_lsn);
+			}
 		}
 
 		if (recv->len > RECV_DATA_BLOCK_SIZE) {
@@ -1686,6 +1710,7 @@ loop:
 		/* Flush all the file pages to disk and invalidate them in
 		the buffer pool */
 
+		ut_d(recv_no_log_write = TRUE);
 		mutex_exit(&(recv_sys->mutex));
 		mutex_exit(&(log_sys->mutex));
 
@@ -1699,6 +1724,7 @@ loop:
 
 		mutex_enter(&(log_sys->mutex));
 		mutex_enter(&(recv_sys->mutex));
+		ut_d(recv_no_log_write = FALSE);
 
 		recv_no_ibuf_operations = FALSE;
 	}
@@ -1910,6 +1936,17 @@ recv_parse_log_rec(
 		return(0);
 	}
 
+#ifdef UNIV_LOG_LSN_DEBUG
+	if (*type == MLOG_LSN) {
+		ib_uint64_t	lsn = (ib_uint64_t) *space << 32 | *page_no;
+# ifdef UNIV_LOG_DEBUG
+		ut_a(lsn == log_sys->old_lsn);
+# else /* UNIV_LOG_DEBUG */
+		ut_a(lsn == recv_sys->recovered_lsn);
+# endif /* UNIV_LOG_DEBUG */
+	}
+#endif /* UNIV_LOG_LSN_DEBUG */
+
 	/* Check that page_no is sensible */
 
 	if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
@@ -2167,6 +2204,12 @@ loop:
 #endif
 			/* In normal mysqld crash recovery we do not try to
 			replay file operations */
+#ifdef UNIV_LOG_LSN_DEBUG
+		} else if (type == MLOG_LSN) {
+			/* Do not add these records to the hash table.
+			The page number and space id fields are misused
+			for something else. */
+#endif /* UNIV_LOG_LSN_DEBUG */
 		} else {
 			recv_add_to_hash_table(type, space, page_no, body,
 					       ptr + len, old_lsn,
@@ -2198,11 +2241,11 @@ loop:
 				= recv_sys->recovered_offset + total_len;
 			recv_previous_parsed_rec_is_multi = 1;
 
-			if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
 #ifdef UNIV_LOG_DEBUG
+			if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
 				recv_check_incomplete_log_recs(ptr, len);
-#endif /* UNIV_LOG_DEBUG */
 			}
+#endif /* UNIV_LOG_DEBUG */
 
 #ifdef UNIV_DEBUG
 			if (log_debug_writes) {
@@ -2266,7 +2309,11 @@ loop:
 				break;
 			}
 
-			if (store_to_hash) {
+			if (store_to_hash
+#ifdef UNIV_LOG_LSN_DEBUG
+			    && type != MLOG_LSN
+#endif /* UNIV_LOG_LSN_DEBUG */
+			    ) {
 				recv_add_to_hash_table(type, space, page_no,
 						       body, ptr + len,
 						       old_lsn,
@@ -2415,8 +2462,7 @@ recv_scan_log_recs(
 	scanned_lsn = start_lsn;
 	more_data = FALSE;
 
-	while (log_block < buf + len && !finished) {
-
+	do {
 		no = log_block_get_hdr_no(log_block);
 		/*
 		fprintf(stderr, "Log block header no %lu\n", no);
@@ -2546,10 +2592,11 @@ recv_scan_log_recs(
 			/* Log data for this group ends here */
 
 			finished = TRUE;
+			break;
 		} else {
 			log_block += OS_FILE_LOG_BLOCK_SIZE;
 		}
-	}
+	} while (log_block < buf + len && !finished);
 
 	*group_scanned_lsn = scanned_lsn;
 
@@ -3104,6 +3151,11 @@ recv_recovery_from_checkpoint_finish(voi
 #ifndef UNIV_LOG_DEBUG
 	recv_sys_free();
 #endif
+	/* Roll back any recovered data dictionary transactions, so
+	that the data dictionary tables will be free of any locks.
+	The data dictionary latch should guarantee that there is at
+	most one data dictionary transaction active at a time. */
+	trx_rollback_or_clean_recovered(FALSE);
 
 	/* Drop partially created indexes. */
 	row_merge_drop_temp_indexes();

=== modified file 'storage/innodb_plugin/mem/mem0mem.c'
--- a/storage/innodb_plugin/mem/mem0mem.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/mem/mem0mem.c	2009-10-08 10:00:49 +0000
@@ -475,16 +475,18 @@ mem_heap_block_free(
 	len = block->len;
 	block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
 
+#ifndef UNIV_HOTBACKUP
+	if (!srv_use_sys_malloc) {
 #ifdef UNIV_MEM_DEBUG
-	/* In the debug version we set the memory to a random combination
-	of hex 0xDE and 0xAD. */
+		/* In the debug version we set the memory to a random
+		combination of hex 0xDE and 0xAD. */
 
-	mem_erase_buf((byte*)block, len);
+		mem_erase_buf((byte*)block, len);
 #else /* UNIV_MEM_DEBUG */
-	UNIV_MEM_ASSERT_AND_FREE(block, len);
+		UNIV_MEM_ASSERT_AND_FREE(block, len);
 #endif /* UNIV_MEM_DEBUG */
 
-#ifndef UNIV_HOTBACKUP
+	}
 	if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
 
 		ut_ad(!buf_block);
@@ -495,6 +497,14 @@ mem_heap_block_free(
 		buf_block_free(buf_block);
 	}
 #else /* !UNIV_HOTBACKUP */
+#ifdef UNIV_MEM_DEBUG
+	/* In the debug version we set the memory to a random
+	combination of hex 0xDE and 0xAD. */
+
+	mem_erase_buf((byte*)block, len);
+#else /* UNIV_MEM_DEBUG */
+	UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
 	ut_free(block);
 #endif /* !UNIV_HOTBACKUP */
 }

=== modified file 'storage/innodb_plugin/mtr/mtr0mtr.c'
--- a/storage/innodb_plugin/mtr/mtr0mtr.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mtr/mtr0mtr.c	2009-10-09 14:13:15 +0000
@@ -35,6 +35,7 @@ Created 11/26/1995 Heikki Tuuri
 #include "log0log.h"
 
 #ifndef UNIV_HOTBACKUP
+# include "log0recv.h"
 /*****************************************************************//**
 Releases the item in the slot given. */
 UNIV_INLINE
@@ -115,7 +116,6 @@ mtr_log_reserve_and_write(
 	dyn_array_t*	mlog;
 	dyn_block_t*	block;
 	ulint		data_size;
-	ibool		success;
 	byte*		first_data;
 
 	ut_ad(mtr);
@@ -134,8 +134,8 @@ mtr_log_reserve_and_write(
 	if (mlog->heap == NULL) {
 		mtr->end_lsn = log_reserve_and_write_fast(
 			first_data, dyn_block_get_used(mlog),
-			&(mtr->start_lsn), &success);
-		if (success) {
+			&mtr->start_lsn);
+		if (mtr->end_lsn) {
 
 			return;
 		}
@@ -182,6 +182,8 @@ mtr_commit(
 	ut_d(mtr->state = MTR_COMMITTING);
 
 #ifndef UNIV_HOTBACKUP
+	/* This is a dirty read, for debugging. */
+	ut_ad(!recv_no_log_write);
 	write_log = mtr->modifications && mtr->n_log_recs;
 
 	if (write_log) {

=== modified file 'storage/innodb_plugin/mysql-test/innodb-analyze.test'
--- a/storage/innodb_plugin/mysql-test/innodb-analyze.test	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-analyze.test	2009-10-12 12:56:02 +0000
@@ -11,6 +11,7 @@
 -- disable_result_log
 -- enable_warnings
 
+let $sample_pages=`select @@innodb_stats_sample_pages`;
 SET GLOBAL innodb_stats_sample_pages=0;
 
 # check that the value has been adjusted to 1
@@ -61,3 +62,4 @@ SET GLOBAL innodb_stats_sample_pages=16;
 ANALYZE TABLE innodb_analyze;
 
 DROP TABLE innodb_analyze;
+EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;

=== added file 'storage/innodb_plugin/mysql-test/innodb-consistent-master.opt'
--- a/storage/innodb_plugin/mysql-test/innodb-consistent-master.opt	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent-master.opt	2009-10-12 12:56:02 +0000
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=2

=== added file 'storage/innodb_plugin/mysql-test/innodb-consistent.result'
--- a/storage/innodb_plugin/mysql-test/innodb-consistent.result	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent.result	2009-10-12 12:56:02 +0000
@@ -0,0 +1,35 @@
+drop table if exists t1;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+begin;
+replace into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+begin;
+insert into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+7
+drop table t1;
+drop table t2;

=== added file 'storage/innodb_plugin/mysql-test/innodb-consistent.test'
--- a/storage/innodb_plugin/mysql-test/innodb-consistent.test	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent.test	2009-10-12 12:56:02 +0000
@@ -0,0 +1,58 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
+# a consistent read of the source table.
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+
+# REPLACE INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+replace into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+# INSERT INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+insert into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+select * from t1;
+drop table t1;
+drop table t2;
+
+connection default;
+disconnect a;
+disconnect b;

=== modified file 'storage/innodb_plugin/mysql-test/innodb-zip.result'
--- a/storage/innodb_plugin/mysql-test/innodb-zip.result	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-zip.result	2009-10-12 12:56:02 +0000
@@ -141,7 +141,7 @@ drop table t1;
 CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
 DROP TABLE t1;

=== modified file 'storage/innodb_plugin/mysql-test/innodb-zip.test'
--- a/storage/innodb_plugin/mysql-test/innodb-zip.test	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb-zip.test	2009-10-12 12:56:02 +0000
@@ -105,7 +105,7 @@ drop table t1;
 --error ER_TOO_BIG_ROWSIZE
 CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
 ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
 INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
 DROP TABLE t1;

=== modified file 'storage/innodb_plugin/mysql-test/innodb_bug34300.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug34300.test	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug34300.test	2009-10-08 09:13:16 +0000
@@ -9,6 +9,7 @@
 -- disable_result_log
 
 # set packet size and reconnect 
+let $max_packet=`select @@global.max_allowed_packet`;
 SET @@global.max_allowed_packet=16777216;
 --connect (newconn, localhost, root,,)
 
@@ -30,3 +31,4 @@ ALTER TABLE bug34300 ADD COLUMN (f10 INT
 SELECT f4, f8 FROM bug34300;
 
 DROP TABLE bug34300;
+EVAL SET @@global.max_allowed_packet=$max_packet;

=== modified file 'storage/innodb_plugin/mysql-test/innodb_bug36169.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug36169.test	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug36169.test	2009-10-12 12:56:02 +0000
@@ -5,6 +5,8 @@
 
 -- source include/have_innodb.inc
 
+let $file_format=`select @@innodb_file_format`;
+let $file_per_table=`select @@innodb_file_per_table`;
 SET GLOBAL innodb_file_format='Barracuda';
 SET GLOBAL innodb_file_per_table=ON;
 
@@ -1153,3 +1155,5 @@ DROP TABLE IF EXISTS table4;
 DROP TABLE IF EXISTS table5;
 DROP TABLE IF EXISTS table6;
 
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;

=== modified file 'storage/innodb_plugin/mysql-test/innodb_bug36172.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug36172.test	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug36172.test	2009-10-12 12:56:02 +0000
@@ -14,6 +14,9 @@ SET storage_engine=InnoDB;
 -- disable_query_log
 -- disable_result_log
 
+let $file_format=`select @@innodb_file_format`;
+let $file_format_check=`select @@innodb_file_format_check`;
+let $file_per_table=`select @@innodb_file_per_table`;
 SET GLOBAL innodb_file_format='Barracuda';
 SET GLOBAL innodb_file_per_table=on;
 
@@ -24,3 +27,6 @@ CHECK TABLE table0 EXTENDED;
 INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col!
 60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
 CHECK TABLE table0 EXTENDED;
 DROP TABLE table0;
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug44369.result'
--- a/storage/innodb_plugin/mysql-test/innodb_bug44369.result	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44369.result	2009-10-12 12:56:02 +0000
@@ -0,0 +1,14 @@
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_row_id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
+Error	1005	Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_TRX_Id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
+Error	1005	Can't create table 'test.bug44369' (errno: -1)

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug44369.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug44369.test	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44369.test	2009-10-12 12:56:02 +0000
@@ -0,0 +1,21 @@
+# This is the test for bug 44369. We should
+# block table creation with columns match
+# some innodb internal reserved key words,
+# both case sensitively and insensitely.
+
+--source include/have_innodb.inc
+
+# This create table operation should fail.
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+
+# This create should fail as well
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_row_id int) engine=innodb;
+
+show errors;
+
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_TRX_Id int) engine=innodb;
+
+show errors;

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug44571.result'
--- a/storage/innodb_plugin/mysql-test/innodb_bug44571.result	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44571.result	2009-10-12 12:56:02 +0000
@@ -0,0 +1,9 @@
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ERROR 42000: Key column 'foo' doesn't exist in table
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+CREATE INDEX bug44571b ON bug44571 (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+DROP TABLE bug44571;

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug44571.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug44571.test	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44571.test	2009-10-12 12:56:02 +0000
@@ -0,0 +1,17 @@
+#
+# Bug#44571 InnoDB Plugin crashes on ADD INDEX
+# http://bugs.mysql.com/44571
+#
+-- source include/have_innodb.inc
+
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+-- error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+# The following will fail, because the CHANGE foo bar was
+# not communicated to InnoDB.
+--error ER_NOT_KEYFILE
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+--error ER_NOT_KEYFILE
+CREATE INDEX bug44571b ON bug44571 (bar);
+DROP TABLE bug44571;

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug46000.result'
--- a/storage/innodb_plugin/mysql-test/innodb_bug46000.result	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug46000.result	2009-10-12 12:56:02 +0000
@@ -0,0 +1,17 @@
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error	1005	Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(id int) engine=innodb;
+create index GEN_CLUST_INDEX on bug46000(id);
+ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
+show errors;
+Level	Code	Message
+Error	1005	Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error	1005	Can't create table '#sql-temporary' (errno: -1)
+create index idx on bug46000(id);
+drop table bug46000;

=== added file 'storage/innodb_plugin/mysql-test/innodb_bug46000.test'
--- a/storage/innodb_plugin/mysql-test/innodb_bug46000.test	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_bug46000.test	2009-10-12 12:56:02 +0000
@@ -0,0 +1,34 @@
+# This is the test for bug 46000. We shall
+# block any index creation with the name of
+# "GEN_CLUST_INDEX", which is the reserved
+# name for innodb default primary index.
+
+--source include/have_innodb.inc
+
+# This 'create table' operation should fail because of
+# using the reserve name as its index name.
+--error ER_CANT_CREATE_TABLE
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+
+# Mixed upper/lower case of the reserved key words
+--error ER_CANT_CREATE_TABLE
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+
+show errors;
+
+create table bug46000(id int) engine=innodb;
+
+# This 'create index' operation should fail.
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+create index GEN_CLUST_INDEX on bug46000(id);
+
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+show errors;
+
+# This 'create index' operation should succeed, no
+# temp table left from last failed create index
+# operation.
+create index idx on bug46000(id);
+
+drop table bug46000;

=== modified file 'storage/innodb_plugin/mysql-test/innodb_file_format.result'
--- a/storage/innodb_plugin/mysql-test/innodb_file_format.result	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.result	2009-10-12 12:56:02 +0000
@@ -42,3 +42,4 @@ ERROR HY000: Incorrect arguments to SET
 select @@innodb_file_format_check;
 @@innodb_file_format_check
 Barracuda
+set global innodb_file_format_check=antelope;

=== modified file 'storage/innodb_plugin/mysql-test/innodb_file_format.test'
--- a/storage/innodb_plugin/mysql-test/innodb_file_format.test	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.test	2009-10-12 12:56:02 +0000
@@ -26,3 +26,4 @@ set global innodb_file_format=on;
 --error ER_WRONG_ARGUMENTS
 set global innodb_file_format=off;
 select @@innodb_file_format_check;
+set global innodb_file_format_check=antelope;

=== modified file 'storage/innodb_plugin/os/os0file.c'
--- a/storage/innodb_plugin/os/os0file.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/os/os0file.c	2009-10-09 14:02:18 +0000
@@ -88,7 +88,9 @@ UNIV_INTERN ibool	os_do_not_call_flush_a
 /* We do not call os_file_flush in every os_file_write. */
 #endif /* UNIV_DO_FLUSH */
 
-#ifndef UNIV_HOTBACKUP
+#ifdef UNIV_HOTBACKUP
+# define os_aio_use_native_aio	FALSE
+#else /* UNIV_HOTBACKUP */
 /* We use these mutexes to protect lseek + file i/o operation, if the
 OS does not provide an atomic pread or pwrite, or similar */
 #define OS_FILE_N_SEEK_MUTEXES	16
@@ -198,7 +200,7 @@ static ulint	os_aio_n_segments	= ULINT_U
 /** If the following is TRUE, read i/o handler threads try to
 wait until a batch of new read requests have been posted */
 static ibool	os_aio_recommend_sleep_for_read_threads	= FALSE;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
 
 UNIV_INTERN ulint	os_n_file_reads		= 0;
 UNIV_INTERN ulint	os_bytes_read_since_printout = 0;
@@ -315,6 +317,12 @@ os_file_get_last_error(
 				" software or another instance\n"
 				"InnoDB: of MySQL."
 				" Please close it to get rid of this error.\n");
+		} else if (err == ERROR_WORKING_SET_QUOTA
+			   || err == ERROR_NO_SYSTEM_RESOURCES) {
+			fprintf(stderr,
+				"InnoDB: The error means that there are no"
+				" sufficient system resources or quota to"
+				" complete the operation.\n");
 		} else {
 			fprintf(stderr,
 				"InnoDB: Some operating system error numbers"
@@ -336,6 +344,9 @@ os_file_get_last_error(
 	} else if (err == ERROR_SHARING_VIOLATION
 		   || err == ERROR_LOCK_VIOLATION) {
 		return(OS_FILE_SHARING_VIOLATION);
+	} else if (err == ERROR_WORKING_SET_QUOTA
+		   || err == ERROR_NO_SYSTEM_RESOURCES) {
+		return(OS_FILE_INSUFFICIENT_RESOURCE);
 	} else {
 		return(100 + err);
 	}
@@ -454,6 +465,10 @@ os_file_handle_error_cond_exit(
 
 		os_thread_sleep(10000000);  /* 10 sec */
 		return(TRUE);
+	} else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
+
+		os_thread_sleep(100000);	/* 100 ms */
+		return(TRUE);
 	} else {
 		if (name) {
 			fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -1245,6 +1260,7 @@ try_again:
 		}
 #endif
 #ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
 		if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
 			/* Do not use unbuffered i/o to log files because
 			value 2 denotes that we do not flush the log at every
@@ -1253,10 +1269,14 @@ try_again:
 			   == SRV_WIN_IO_UNBUFFERED) {
 			attributes = attributes | FILE_FLAG_NO_BUFFERING;
 		}
-#endif
+# else /* !UNIV_HOTBACKUP */
+		attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
 	} else if (purpose == OS_FILE_NORMAL) {
 		attributes = 0;
 #ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
 		if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
 			/* Do not use unbuffered i/o to log files because
 			value 2 denotes that we do not flush the log at every
@@ -1265,7 +1285,10 @@ try_again:
 			   == SRV_WIN_IO_UNBUFFERED) {
 			attributes = attributes | FILE_FLAG_NO_BUFFERING;
 		}
-#endif
+# else /* !UNIV_HOTBACKUP */
+		attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
 	} else {
 		attributes = 0;
 		ut_error;
@@ -2022,7 +2045,9 @@ os_file_pread(
 				offset */
 {
 	off_t	offs;
+#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
 	ssize_t	n_bytes;
+#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
 
 	ut_a((offset & 0xFFFFFFFFUL) == offset);
 
@@ -2061,16 +2086,20 @@ os_file_pread(
 	{
 		off_t	ret_offset;
 		ssize_t	ret;
+#ifndef UNIV_HOTBACKUP
 		ulint	i;
+#endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_reads++;
 		os_mutex_exit(os_file_count_mutex);
 
+#ifndef UNIV_HOTBACKUP
 		/* Protect the seek / read operation with a mutex */
 		i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
 		os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 		ret_offset = lseek(file, offs, SEEK_SET);
 
@@ -2080,7 +2109,9 @@ os_file_pread(
 			ret = read(file, buf, (ssize_t)n);
 		}
 
+#ifndef UNIV_HOTBACKUP
 		os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_reads--;
@@ -2158,16 +2189,20 @@ os_file_pwrite(
 #else
 	{
 		off_t	ret_offset;
+# ifndef UNIV_HOTBACKUP
 		ulint	i;
+# endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_writes++;
 		os_mutex_exit(os_file_count_mutex);
 
+# ifndef UNIV_HOTBACKUP
 		/* Protect the seek / write operation with a mutex */
 		i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
 		os_mutex_enter(os_file_seek_mutexes[i]);
+# endif /* UNIV_HOTBACKUP */
 
 		ret_offset = lseek(file, offs, SEEK_SET);
 
@@ -2193,7 +2228,9 @@ os_file_pwrite(
 # endif /* UNIV_DO_FLUSH */
 
 func_exit:
+# ifndef UNIV_HOTBACKUP
 		os_mutex_exit(os_file_seek_mutexes[i]);
+# endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_writes--;
@@ -2227,7 +2264,9 @@ os_file_read(
 	DWORD		low;
 	DWORD		high;
 	ibool		retry;
+#ifndef UNIV_HOTBACKUP
 	ulint		i;
+#endif /* !UNIV_HOTBACKUP */
 
 	ut_a((offset & 0xFFFFFFFFUL) == offset);
 
@@ -2246,16 +2285,20 @@ try_again:
 	os_n_pending_reads++;
 	os_mutex_exit(os_file_count_mutex);
 
+#ifndef UNIV_HOTBACKUP
 	/* Protect the seek / read operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
 	os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
 	if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
+#ifndef UNIV_HOTBACKUP
 		os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_reads--;
@@ -2266,7 +2309,9 @@ try_again:
 
 	ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
+#ifndef UNIV_HOTBACKUP
 	os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	os_mutex_enter(os_file_count_mutex);
 	os_n_pending_reads--;
@@ -2275,7 +2320,7 @@ try_again:
 	if (ret && len == n) {
 		return(TRUE);
 	}
-#else
+#else /* __WIN__ */
 	ibool	retry;
 	ssize_t	ret;
 
@@ -2294,7 +2339,7 @@ try_again:
 		"InnoDB: Was only able to read %ld.\n",
 		(ulong)n, (ulong)offset_high,
 		(ulong)offset, (long)ret);
-#endif
+#endif /* __WIN__ */
 #ifdef __WIN__
 error_handling:
 #endif
@@ -2343,7 +2388,9 @@ os_file_read_no_error_handling(
 	DWORD		low;
 	DWORD		high;
 	ibool		retry;
+#ifndef UNIV_HOTBACKUP
 	ulint		i;
+#endif /* !UNIV_HOTBACKUP */
 
 	ut_a((offset & 0xFFFFFFFFUL) == offset);
 
@@ -2362,16 +2409,20 @@ try_again:
 	os_n_pending_reads++;
 	os_mutex_exit(os_file_count_mutex);
 
+#ifndef UNIV_HOTBACKUP
 	/* Protect the seek / read operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
 	os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
 	if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
+#ifndef UNIV_HOTBACKUP
 		os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_reads--;
@@ -2382,7 +2433,9 @@ try_again:
 
 	ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
+#ifndef UNIV_HOTBACKUP
 	os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	os_mutex_enter(os_file_count_mutex);
 	os_n_pending_reads--;
@@ -2391,7 +2444,7 @@ try_again:
 	if (ret && len == n) {
 		return(TRUE);
 	}
-#else
+#else /* __WIN__ */
 	ibool	retry;
 	ssize_t	ret;
 
@@ -2404,7 +2457,7 @@ try_again:
 
 		return(TRUE);
 	}
-#endif
+#endif /* __WIN__ */
 #ifdef __WIN__
 error_handling:
 #endif
@@ -2463,9 +2516,11 @@ os_file_write(
 	DWORD		ret2;
 	DWORD		low;
 	DWORD		high;
-	ulint		i;
 	ulint		n_retries	= 0;
 	ulint		err;
+#ifndef UNIV_HOTBACKUP
+	ulint		i;
+#endif /* !UNIV_HOTBACKUP */
 
 	ut_a((offset & 0xFFFFFFFF) == offset);
 
@@ -2482,16 +2537,20 @@ retry:
 	os_n_pending_writes++;
 	os_mutex_exit(os_file_count_mutex);
 
+#ifndef UNIV_HOTBACKUP
 	/* Protect the seek / write operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 
 	os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
 
 	if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
 
+#ifndef UNIV_HOTBACKUP
 		os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 		os_mutex_enter(os_file_count_mutex);
 		os_n_pending_writes--;
@@ -2525,7 +2584,9 @@ retry:
 	}
 # endif /* UNIV_DO_FLUSH */
 
+#ifndef UNIV_HOTBACKUP
 	os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
 
 	os_mutex_enter(os_file_count_mutex);
 	os_n_pending_writes--;
@@ -3371,9 +3432,21 @@ void
 os_aio_simulated_put_read_threads_to_sleep(void)
 /*============================================*/
 {
+
+/* The idea of putting background IO threads to sleep is only for
+Windows when using simulated AIO. Windows XP seems to schedule
+background threads too eagerly to allow for coalescing during
+readahead requests. */
+#ifdef __WIN__
 	os_aio_array_t*	array;
 	ulint		g;
 
+	if (os_aio_use_native_aio) {
+		/* We do not use simulated aio: do nothing */
+
+		return;
+	}
+
 	os_aio_recommend_sleep_for_read_threads	= TRUE;
 
 	for (g = 0; g < os_aio_n_segments; g++) {
@@ -3384,6 +3457,7 @@ os_aio_simulated_put_read_threads_to_sle
 			os_event_reset(os_aio_segment_wait_events[g]);
 		}
 	}
+#endif /* __WIN__ */
 }
 
 /*******************************************************************//**

=== modified file 'storage/innodb_plugin/page/page0cur.c'
--- a/storage/innodb_plugin/page/page0cur.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/page/page0cur.c	2009-10-09 14:13:15 +0000
@@ -1195,7 +1195,7 @@ page_cur_insert_rec_zip_reorg(
 	}
 
 	/* Out of space: restore the page */
-	if (!page_zip_decompress(page_zip, page)) {
+	if (!page_zip_decompress(page_zip, page, FALSE)) {
 		ut_error; /* Memory corrupted? */
 	}
 	ut_ad(page_validate(page, index));

=== modified file 'storage/innodb_plugin/page/page0page.c'
--- a/storage/innodb_plugin/page/page0page.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/page/page0page.c	2009-10-09 14:13:15 +0000
@@ -45,7 +45,7 @@ Created 2/2/1994 Heikki Tuuri
 			==============
 
 The index page consists of a page header which contains the page's
-id and other information. On top of it are the the index records
+id and other information. On top of it are the index records
 in a heap linked into a one way linear list according to alphabetic order.
 
 Just below page end is an array of pointers which we call page directory,
@@ -679,7 +679,7 @@ page_copy_rec_list_end(
 
 				if (UNIV_UNLIKELY
 				    (!page_zip_decompress(new_page_zip,
-							  new_page))) {
+							  new_page, FALSE))) {
 					ut_error;
 				}
 				ut_ad(page_validate(new_page, index));
@@ -792,7 +792,7 @@ page_copy_rec_list_start(
 
 				if (UNIV_UNLIKELY
 				    (!page_zip_decompress(new_page_zip,
-							  new_page))) {
+							  new_page, FALSE))) {
 					ut_error;
 				}
 				ut_ad(page_validate(new_page, index));

=== modified file 'storage/innodb_plugin/page/page0zip.c'
--- a/storage/innodb_plugin/page/page0zip.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/page/page0zip.c	2009-10-09 14:13:15 +0000
@@ -47,8 +47,10 @@ Created June 2005 by Marko Makela
 # define buf_LRU_stat_inc_unzip()			((void) 0)
 #endif /* !UNIV_HOTBACKUP */
 
+#ifndef UNIV_HOTBACKUP
 /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
 UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+#endif /* !UNIV_HOTBACKUP */
 
 /* Please refer to ../include/page0zip.ic for a description of the
 compressed page format. */
@@ -1144,7 +1146,9 @@ page_zip_compress(
 	ulint*		offsets	= NULL;
 	ulint		n_blobs	= 0;
 	byte*		storage;/* storage of uncompressed columns */
+#ifndef UNIV_HOTBACKUP
 	ullint		usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
 #ifdef PAGE_ZIP_COMPRESS_DBG
 	FILE*		logfile = NULL;
 #endif
@@ -1208,7 +1212,9 @@ page_zip_compress(
 		}
 	}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 	page_zip_stat[page_zip->ssize - 1].compressed++;
+#endif /* !UNIV_HOTBACKUP */
 
 	if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
 			  >= page_zip_get_size(page_zip))) {
@@ -1345,8 +1351,10 @@ err_exit:
 			fclose(logfile);
 		}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 		page_zip_stat[page_zip->ssize - 1].compressed_usec
 			+= ut_time_us(NULL) - usec;
+#endif /* !UNIV_HOTBACKUP */
 		return(FALSE);
 	}
 
@@ -1404,12 +1412,14 @@ err_exit:
 		fclose(logfile);
 	}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 	{
 		page_zip_stat_t*	zip_stat
 			= &page_zip_stat[page_zip->ssize - 1];
 		zip_stat->compressed_ok++;
 		zip_stat->compressed_usec += ut_time_us(NULL) - usec;
 	}
+#endif /* !UNIV_HOTBACKUP */
 
 	return(TRUE);
 }
@@ -2811,7 +2821,11 @@ page_zip_decompress(
 /*================*/
 	page_zip_des_t*	page_zip,/*!< in: data, ssize;
 				out: m_start, m_end, m_nonempty, n_blobs */
-	page_t*		page)	/*!< out: uncompressed page, may be trashed */
+	page_t*		page,	/*!< out: uncompressed page, may be trashed */
+	ibool		all)	/*!< in: TRUE=decompress the whole page;
+				FALSE=verify but do not copy some
+				page header fields that should not change
+				after page creation */
 {
 	z_stream	d_stream;
 	dict_index_t*	index	= NULL;
@@ -2820,7 +2834,9 @@ page_zip_decompress(
 	ulint		trx_id_col = ULINT_UNDEFINED;
 	mem_heap_t*	heap;
 	ulint*		offsets;
+#ifndef UNIV_HOTBACKUP
 	ullint		usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
 
 	ut_ad(page_zip_simple_validate(page_zip));
 	UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
@@ -2839,13 +2855,36 @@ page_zip_decompress(
 	heap = mem_heap_create(n_dense * (3 * sizeof *recs) + UNIV_PAGE_SIZE);
 	recs = mem_heap_alloc(heap, n_dense * (2 * sizeof *recs));
 
+	if (all) {
+		/* Copy the page header. */
+		memcpy(page, page_zip->data, PAGE_DATA);
+	} else {
+		/* Check that the bytes that we skip are identical. */
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+		ut_a(!memcmp(FIL_PAGE_TYPE + page,
+			     FIL_PAGE_TYPE + page_zip->data,
+			     PAGE_HEADER - FIL_PAGE_TYPE));
+		ut_a(!memcmp(PAGE_HEADER + PAGE_LEVEL + page,
+			     PAGE_HEADER + PAGE_LEVEL + page_zip->data,
+			     PAGE_DATA - (PAGE_HEADER + PAGE_LEVEL)));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+		/* Copy the mutable parts of the page header. */
+		memcpy(page, page_zip->data, FIL_PAGE_TYPE);
+		memcpy(PAGE_HEADER + page, PAGE_HEADER + page_zip->data,
+		       PAGE_LEVEL - PAGE_N_DIR_SLOTS);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+		/* Check that the page headers match after copying. */
+		ut_a(!memcmp(page, page_zip->data, PAGE_DATA));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+	}
+
 #ifdef UNIV_ZIP_DEBUG
-	/* Clear the page. */
-	memset(page, 0x55, UNIV_PAGE_SIZE);
+	/* Clear the uncompressed page, except the header. */
+	memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
 #endif /* UNIV_ZIP_DEBUG */
-	UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
-	/* Copy the page header. */
-	memcpy(page, page_zip->data, PAGE_DATA);
+	UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
 
 	/* Copy the page directory. */
 	if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -2976,12 +3015,14 @@ err_exit:
 
 	page_zip_fields_free(index);
 	mem_heap_free(heap);
+#ifndef UNIV_HOTBACKUP
 	{
 		page_zip_stat_t*	zip_stat
 			= &page_zip_stat[page_zip->ssize - 1];
 		zip_stat->decompressed++;
 		zip_stat->decompressed_usec += ut_time_us(NULL) - usec;
 	}
+#endif /* !UNIV_HOTBACKUP */
 
 	/* Update the stat counter for LRU policy. */
 	buf_LRU_stat_inc_unzip();
@@ -3084,7 +3125,7 @@ page_zip_validate_low(
 #endif /* UNIV_DEBUG_VALGRIND */
 
 	temp_page_zip = *page_zip;
-	valid = page_zip_decompress(&temp_page_zip, temp_page);
+	valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
 	if (!valid) {
 		fputs("page_zip_validate(): failed to decompress\n", stderr);
 		goto func_exit;
@@ -4362,8 +4403,8 @@ IMPORTANT: if page_zip_reorganize() is i
 non-clustered index, the caller must update the insert buffer free
 bits in the same mini-transaction in such a way that the modification
 will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
 UNIV_INTERN
 ibool
 page_zip_reorganize(
@@ -4428,9 +4469,6 @@ page_zip_reorganize(
 
 	if (UNIV_UNLIKELY(!page_zip_compress(page_zip, page, index, mtr))) {
 
-		/* Restore the old page and exit. */
-		buf_frame_copy(page, temp_page);
-
 #ifndef UNIV_HOTBACKUP
 		buf_block_free(temp_block);
 #endif /* !UNIV_HOTBACKUP */
@@ -4591,7 +4629,8 @@ corrupt:
 		memcpy(page_zip->data + page_zip_get_size(page_zip)
 		       - trailer_size, ptr + 8 + size, trailer_size);
 
-		if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page))) {
+		if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page,
+						       TRUE))) {
 
 			goto corrupt;
 		}

=== modified file 'storage/innodb_plugin/plug.in'
--- a/storage/innodb_plugin/plug.in	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/plug.in	2009-10-12 12:00:56 +0000
@@ -37,33 +37,75 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin,  [
 	irix*|osf*|sysv5uw7*|openbsd*)
 		CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
 	*solaris*|*SunOS*)
-		# Begin Solaris atomic function checks
-		AC_CHECK_FUNCS(atomic_cas_ulong atomic_cas_32 \
-			       atomic_cas_64 atomic_add_long,
-			AC_DEFINE(
-				[HAVE_SOLARIS_ATOMICS],
-				[1],
-				[Define to 1 if Solaris supports \
-				 atomic functions.]))
-		### End Solaris atomic function checks
-
 		CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
   esac
+
   INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
-  case "$target_cpu---$target_os" in
-	x86_64---*)
+
+  case "$target_cpu" in
+	x86_64)
 		# The AMD64 ABI forbids absolute addresses in shared libraries
 		;;
-	*---solaris*|*---SunOS*)
-		# Shared objects must be linked from PIC code on Solaris.
-		;;
-	*86---)
+	*86)
 		# Use absolute addresses on IA-32
 		INNODB_DYNAMIC_CFLAGS="$INNODB_DYNAMIC_CFLAGS -prefer-non-pic"
 		;;
   esac
   AC_SUBST(INNODB_DYNAMIC_CFLAGS)
+
+  AC_MSG_CHECKING(whether GCC atomic builtins are available)
+  # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
+  AC_TRY_RUN(
+    [
+      int main()
+      {
+	long	x;
+	long	y;
+	long	res;
+	char	c;
+
+	x = 10;
+	y = 123;
+	res = __sync_bool_compare_and_swap(&x, x, y);
+	if (!res || x != y) {
+          return(1);
+        }
+
+	x = 10;
+	y = 123;
+	res = __sync_bool_compare_and_swap(&x, x + 1, y);
+	if (res || x != 10) {
+          return(1);
+        }
+
+	x = 10;
+	y = 123;
+	res = __sync_add_and_fetch(&x, y);
+	if (res != 123 + 10 || x != 123 + 10) {
+	  return(1);
+	}
+
+	c = 10;
+	res = __sync_lock_test_and_set(&c, 123);
+	if (res != 10 || c != 123) {
+	  return(1);
+	}
+
+	return(0);
+      }
+    ],
+    [
+      AC_DEFINE([HAVE_IB_GCC_ATOMIC_BUILTINS], [1],
+                [GCC atomic builtins are available])
+      AC_MSG_RESULT(yes)
+    ],
+    [
+      AC_MSG_RESULT(no)
+    ]
+  )
+
   AC_MSG_CHECKING(whether pthread_t can be used by GCC atomic builtins)
+  # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
   AC_TRY_RUN(
     [
       #include <pthread.h>
@@ -84,47 +126,73 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin,  [
       }
     ],
     [
-      AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+      AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_GCC], [1],
                 [pthread_t can be used by GCC atomic builtins])
       AC_MSG_RESULT(yes)
     ],
     [
       AC_MSG_RESULT(no)
     ]
-    )
+  )
 
-  # Try using solaris atomics on SunOS if GCC atomics are not available
-  AC_CHECK_DECLS(
-    [HAVE_ATOMIC_PTHREAD_T],
-    [
-      AC_MSG_NOTICE(no need to check pthread_t size)
-    ],
-    [
-      AC_CHECK_DECLS(
-        [HAVE_SOLARIS_ATOMICS],
-        [
-          AC_MSG_CHECKING(checking if pthread_t size is integral)
-          AC_TRY_RUN(
-            [
-              #include <pthread.h>
-              int main()
-              {
-                pthread_t x = 0;
-                return(0);
-              }
-            ],
-            [
-              AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+  AC_MSG_CHECKING(whether Solaris libc atomic functions are available)
+  # either define HAVE_IB_SOLARIS_ATOMICS or not
+  AC_CHECK_FUNCS(atomic_add_long \
+		 atomic_cas_32 \
+		 atomic_cas_64 \
+		 atomic_cas_ulong,
+
+		 AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1],
+			   [Define to 1 if Solaris libc atomic functions \
+			    are available])
+  )
+
+  AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions)
+  # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not
+  AC_TRY_RUN(
+    [
+      #include <pthread.h>
+      #include <string.h>
+
+      int main(int argc, char** argv) {
+        pthread_t       x1;
+        pthread_t       x2;
+        pthread_t       x3;
+
+        memset(&x1, 0x0, sizeof(x1));
+        memset(&x2, 0x0, sizeof(x2));
+        memset(&x3, 0x0, sizeof(x3));
+
+        if (sizeof(pthread_t) == 4) {
+        
+          atomic_cas_32(&x1, x2, x3);
+        
+        } else if (sizeof(pthread_t) == 8) {
+        
+          atomic_cas_64(&x1, x2, x3);
+        
+        } else {
+        
+          return(1);
+        }
+
+	return(0);
+      }
+    ],
+    [
+      AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS], [1],
                 [pthread_t can be used by solaris atomics])
-              AC_MSG_RESULT(yes)
-              # size of pthread_t is needed for typed solaris atomics
-              AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
-            ],
-            [
-              AC_MSG_RESULT(no)
-            ])
-        ])
-    ])
+      AC_MSG_RESULT(yes)
+    ],
+    [
+      AC_MSG_RESULT(no)
+    ]
+  )
+
+  # this is needed to know which one of atomic_cas_32() or atomic_cas_64()
+  # to use in the source
+  AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
+
   # Check for x86 PAUSE instruction
   AC_MSG_CHECKING(for x86 PAUSE instruction)
   # We have to actually try running the test program, because of a bug
@@ -141,7 +209,7 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin,  [
       }
     ],
     [
-      AC_DEFINE([IB_HAVE_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+      AC_DEFINE([HAVE_IB_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
       AC_MSG_RESULT(yes)
     ],
     [

=== modified file 'storage/innodb_plugin/rem/rem0cmp.c'
--- a/storage/innodb_plugin/rem/rem0cmp.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/rem/rem0cmp.c	2009-10-08 10:00:49 +0000
@@ -36,7 +36,7 @@ Created 7/1/1994 Heikki Tuuri
 
 The records are put into alphabetical order in the following
 way: let F be the first field where two records disagree.
-If there is a character in some position n where the the
+If there is a character in some position n where the
 records disagree, the order is determined by comparison of
 the characters at position n, possibly after
 collating transformation. If there is no such character,
@@ -76,7 +76,7 @@ cmp_debug_dtuple_rec_with_match(
 /*************************************************************//**
 This function is used to compare two data fields for which the data type
 is such that we must use MySQL code to compare them. The prototype here
-must be a copy of the the one in ha_innobase.cc!
+must be a copy of the one in ha_innobase.cc!
 @return	1, 0, -1, if a is greater, equal, less than b, respectively */
 extern
 int
@@ -399,7 +399,7 @@ next_byte:
 /*************************************************************//**
 This function is used to compare a data tuple to a physical record.
 Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
 have either m >= n fields, or it must differ from dtuple in some of
 the m fields rec has. If rec has an externally stored field we do not
 compare it but return with value 0 if such a comparison should be

=== added file 'storage/innodb_plugin/revert_gen.sh'
--- a/storage/innodb_plugin/revert_gen.sh	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/revert_gen.sh	2009-10-12 12:56:02 +0000
@@ -0,0 +1,8 @@
+#!/bin/bash
+#
+# revert changes to all generated files. this is useful in some situations
+# when merging changes between branches.
+
+set -eu
+
+svn revert include/pars0grm.h pars/pars0grm.h pars/lexyy.c pars/pars0grm.c

=== modified file 'storage/innodb_plugin/row/row0ins.c'
--- a/storage/innodb_plugin/row/row0ins.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/row/row0ins.c	2009-10-09 14:13:15 +0000
@@ -1191,7 +1191,7 @@ row_ins_check_foreign_constraint(
 /*=============================*/
 	ibool		check_ref,/*!< in: TRUE if we want to check that
 				the referenced table is ok, FALSE if we
-				want to to check the foreign key table */
+				want to check the foreign key table */
 	dict_foreign_t*	foreign,/*!< in: foreign constraint; NOTE that the
 				tables mentioned in it must be in the
 				dictionary cache if they exist at all */

=== modified file 'storage/innodb_plugin/row/row0merge.c'
--- a/storage/innodb_plugin/row/row0merge.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/row/row0merge.c	2009-10-09 14:13:15 +0000
@@ -60,9 +60,19 @@ Completed by Sunny Bains and Marko Makel
 #ifdef UNIV_DEBUG
 /** Set these in order ot enable debug printout. */
 /* @{ */
+/** Log the outcome of each row_merge_cmp() call, comparing records. */
 static ibool	row_merge_print_cmp;
+/** Log each record read from temporary file. */
 static ibool	row_merge_print_read;
+/** Log each record write to temporary file. */
 static ibool	row_merge_print_write;
+/** Log each row_merge_blocks() call, merging two blocks of records to
+a bigger one. */
+static ibool	row_merge_print_block;
+/** Log each block read from temporary file. */
+static ibool	row_merge_print_block_read;
+/** Log each block read from temporary file. */
+static ibool	row_merge_print_block_write;
 /* @} */
 #endif /* UNIV_DEBUG */
 
@@ -109,8 +119,9 @@ typedef struct row_merge_buf_struct row_
 
 /** Information about temporary files used in merge sort */
 struct merge_file_struct {
-	int	fd;		/*!< file descriptor */
-	ulint	offset;		/*!< file offset */
+	int		fd;		/*!< file descriptor */
+	ulint		offset;		/*!< file offset (end of file) */
+	ib_uint64_t	n_rec;		/*!< number of records in the file */
 };
 
 /** Information about temporary files used in merge sort */
@@ -682,6 +693,13 @@ row_merge_read(
 	ib_uint64_t	ofs = ((ib_uint64_t) offset) * sizeof *buf;
 	ibool		success;
 
+#ifdef UNIV_DEBUG
+	if (row_merge_print_block_read) {
+		fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
+			fd, (ulong) offset);
+	}
+#endif /* UNIV_DEBUG */
+
 	success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
 						 (ulint) (ofs & 0xFFFFFFFF),
 						 (ulint) (ofs >> 32),
@@ -709,6 +727,13 @@ row_merge_write(
 	ib_uint64_t	ofs = ((ib_uint64_t) offset)
 		* sizeof(row_merge_block_t);
 
+#ifdef UNIV_DEBUG
+	if (row_merge_print_block_write) {
+		fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
+			fd, (ulong) offset);
+	}
+#endif /* UNIV_DEBUG */
+
 	return(UNIV_LIKELY(os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
 					 (ulint) (ofs & 0xFFFFFFFF),
 					 (ulint) (ofs >> 32),
@@ -718,7 +743,7 @@ row_merge_write(
 /********************************************************************//**
 Read a merge record.
 @return	pointer to next record, or NULL on I/O error or end of list */
-static
+static __attribute__((nonnull))
 const byte*
 row_merge_read_rec(
 /*===============*/
@@ -1070,7 +1095,7 @@ row_merge_cmp(
 Reads clustered index of the table and create temporary files
 containing the index entries for the indexes to be built.
 @return	DB_SUCCESS or error */
-static
+static __attribute__((nonnull))
 ulint
 row_merge_read_clustered_index(
 /*===========================*/
@@ -1233,6 +1258,7 @@ row_merge_read_clustered_index(
 
 			if (UNIV_LIKELY
 			    (row && row_merge_buf_add(buf, row, ext))) {
+				file->n_rec++;
 				continue;
 			}
 
@@ -1274,14 +1300,19 @@ err_exit:
 			UNIV_MEM_INVALID(block[0], sizeof block[0]);
 			merge_buf[i] = row_merge_buf_empty(buf);
 
-			/* Try writing the record again, now that
-			the buffer has been written out and emptied. */
+			if (UNIV_LIKELY(row != NULL)) {
+				/* Try writing the record again, now
+				that the buffer has been written out
+				and emptied. */
+
+				if (UNIV_UNLIKELY
+				    (!row_merge_buf_add(buf, row, ext))) {
+					/* An empty buffer should have enough
+					room for at least one record. */
+					ut_error;
+				}
 
-			if (UNIV_UNLIKELY
-			    (row && !row_merge_buf_add(buf, row, ext))) {
-				/* An empty buffer should have enough
-				room for at least one record. */
-				ut_error;
+				file->n_rec++;
 			}
 		}
 
@@ -1320,7 +1351,7 @@ func_exit:
 		b2 = row_merge_write_rec(&block[2], &buf[2], b2,	\
 					 of->fd, &of->offset,		\
 					 mrec##N, offsets##N);		\
-		if (UNIV_UNLIKELY(!b2)) {				\
+		if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) {	\
 			goto corrupt;					\
 		}							\
 		b##N = row_merge_read_rec(&block[N], &buf[N],		\
@@ -1336,14 +1367,14 @@ func_exit:
 	} while (0)
 
 /*************************************************************//**
-Merge two blocks of linked lists on disk and write a bigger block.
+Merge two blocks of records on disk and write a bigger block.
 @return	DB_SUCCESS or error code */
 static
 ulint
 row_merge_blocks(
 /*=============*/
 	const dict_index_t*	index,	/*!< in: index being created */
-	merge_file_t*		file,	/*!< in/out: file containing
+	const merge_file_t*	file,	/*!< in: file containing
 					index entries */
 	row_merge_block_t*	block,	/*!< in/out: 3 buffers */
 	ulint*			foffs0,	/*!< in/out: offset of first
@@ -1366,6 +1397,17 @@ row_merge_blocks(
 	ulint*		offsets0;/* offsets of mrec0 */
 	ulint*		offsets1;/* offsets of mrec1 */
 
+#ifdef UNIV_DEBUG
+	if (row_merge_print_block) {
+		fprintf(stderr,
+			"row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
+			" = fd=%d ofs=%lu\n",
+			file->fd, (ulong) *foffs0,
+			file->fd, (ulong) *foffs1,
+			of->fd, (ulong) of->offset);
+	}
+#endif /* UNIV_DEBUG */
+
 	heap = row_merge_heap_create(index, &offsets0, &offsets1);
 
 	/* Write a record and read the next record.  Split the output
@@ -1438,16 +1480,87 @@ done1:
 }
 
 /*************************************************************//**
+Copy a block of index entries.
+@return	TRUE on success, FALSE on failure */
+static __attribute__((nonnull))
+ibool
+row_merge_blocks_copy(
+/*==================*/
+	const dict_index_t*	index,	/*!< in: index being created */
+	const merge_file_t*	file,	/*!< in: input file */
+	row_merge_block_t*	block,	/*!< in/out: 3 buffers */
+	ulint*			foffs0,	/*!< in/out: input file offset */
+	merge_file_t*		of)	/*!< in/out: output file */
+{
+	mem_heap_t*	heap;	/*!< memory heap for offsets0, offsets1 */
+
+	mrec_buf_t	buf[3];	/*!< buffer for handling
+				split mrec in block[] */
+	const byte*	b0;	/*!< pointer to block[0] */
+	byte*		b2;	/*!< pointer to block[2] */
+	const mrec_t*	mrec0;	/*!< merge rec, points to block[0] */
+	ulint*		offsets0;/* offsets of mrec0 */
+	ulint*		offsets1;/* dummy offsets */
+
+#ifdef UNIV_DEBUG
+	if (row_merge_print_block) {
+		fprintf(stderr,
+			"row_merge_blocks_copy fd=%d ofs=%lu"
+			" = fd=%d ofs=%lu\n",
+			file->fd, (ulong) foffs0,
+			of->fd, (ulong) of->offset);
+	}
+#endif /* UNIV_DEBUG */
+
+	heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+	/* Write a record and read the next record.  Split the output
+	file in two halves, which can be merged on the following pass. */
+
+	if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+corrupt:
+		mem_heap_free(heap);
+		return(FALSE);
+	}
+
+	b0 = block[0];
+	b2 = block[2];
+
+	b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
+				foffs0, &mrec0, offsets0);
+	if (UNIV_UNLIKELY(!b0 && mrec0)) {
+
+		goto corrupt;
+	}
+
+	if (mrec0) {
+		/* append all mrec0 to output */
+		for (;;) {
+			ROW_MERGE_WRITE_GET_NEXT(0, goto done0);
+		}
+	}
+done0:
+
+	/* The file offset points to the beginning of the last page
+	that has been read.  Update it to point to the next block. */
+	(*foffs0)++;
+
+	mem_heap_free(heap);
+	return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
+	       != NULL);
+}
+
+/*************************************************************//**
 Merge disk files.
 @return	DB_SUCCESS or error code */
-static
+static __attribute__((nonnull))
 ulint
 row_merge(
 /*======*/
 	const dict_index_t*	index,	/*!< in: index being created */
 	merge_file_t*		file,	/*!< in/out: file containing
 					index entries */
-	ulint			half,	/*!< in: half the file */
+	ulint*			half,	/*!< in/out: half the file */
 	row_merge_block_t*	block,	/*!< in/out: 3 buffers */
 	int*			tmpfd,	/*!< in/out: temporary file handle */
 	TABLE*			table)	/*!< in/out: MySQL table, for
@@ -1458,43 +1571,75 @@ row_merge(
 	ulint		foffs1;	/*!< second input offset */
 	ulint		error;	/*!< error code */
 	merge_file_t	of;	/*!< output file */
+	const ulint	ihalf	= *half;
+				/*!< half the input file */
+	ulint		ohalf;	/*!< half the output file */
 
 	UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
-	ut_ad(half > 0);
+	ut_ad(ihalf < file->offset);
 
 	of.fd = *tmpfd;
 	of.offset = 0;
+	of.n_rec = 0;
 
 	/* Merge blocks to the output file. */
+	ohalf = 0;
 	foffs0 = 0;
-	foffs1 = half;
+	foffs1 = ihalf;
+
+	for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
+		ulint	ahalf;	/*!< arithmetic half the input file */
 
-	for (; foffs0 < half && foffs1 < file->offset; foffs0++, foffs1++) {
 		error = row_merge_blocks(index, file, block,
 					 &foffs0, &foffs1, &of, table);
 
 		if (error != DB_SUCCESS) {
 			return(error);
 		}
+
+		/* Record the offset of the output file when
+		approximately half the output has been generated.  In
+		this way, the next invocation of row_merge() will
+		spend most of the time in this loop.  The initial
+		estimate is ohalf==0. */
+		ahalf = file->offset / 2;
+		ut_ad(ohalf <= of.offset);
+
+		/* Improve the estimate until reaching half the input
+		file size, or we can not get any closer to it.  All
+		comparands should be non-negative when !(ohalf < ahalf)
+		because ohalf <= of.offset. */
+		if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) {
+			ohalf = of.offset;
+		}
 	}
 
-	/* Copy the last block, if there is one. */
-	while (foffs0 < half) {
-		if (!row_merge_read(file->fd, foffs0++, block)
-		    || !row_merge_write(of.fd, of.offset++, block)) {
+	/* Copy the last blocks, if there are any. */
+
+	while (foffs0 < ihalf) {
+		if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
 			return(DB_CORRUPTION);
 		}
 	}
+
+	ut_ad(foffs0 == ihalf);
+
 	while (foffs1 < file->offset) {
-		if (!row_merge_read(file->fd, foffs1++, block)
-		    || !row_merge_write(of.fd, of.offset++, block)) {
+		if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
 			return(DB_CORRUPTION);
 		}
 	}
 
+	ut_ad(foffs1 == file->offset);
+
+	if (UNIV_UNLIKELY(of.n_rec != file->n_rec)) {
+		return(DB_CORRUPTION);
+	}
+
 	/* Swap file descriptors for the next pass. */
 	*tmpfd = file->fd;
 	*file = of;
+	*half = ohalf;
 
 	UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
 
@@ -1517,20 +1662,25 @@ row_merge_sort(
 					reporting erroneous key value
 					if applicable */
 {
-	ulint	blksz;	/*!< block size */
+	ulint	half = file->offset / 2;
+
+	/* The file should always contain at least one byte (the end
+	of file marker).  Thus, it must be at least one block. */
+	ut_ad(file->offset > 0);
 
-	for (blksz = 1; blksz < file->offset; blksz *= 2) {
-		ulint	half;
+	do {
 		ulint	error;
 
-		ut_ad(ut_is_2pow(blksz));
-		half = ut_2pow_round((file->offset + (blksz - 1)) / 2, blksz);
-		error = row_merge(index, file, half, block, tmpfd, table);
+		error = row_merge(index, file, &half, block, tmpfd, table);
 
 		if (error != DB_SUCCESS) {
 			return(error);
 		}
-	}
+
+		/* half > 0 should hold except when the file consists
+		of one block.  No need to merge further then. */
+		ut_ad(half > 0 || file->offset == 1);
+	} while (half < file->offset && half > 0);
 
 	return(DB_SUCCESS);
 }
@@ -1797,7 +1947,15 @@ row_merge_drop_index(
 	static const char str1[] =
 		"PROCEDURE DROP_INDEX_PROC () IS\n"
 		"BEGIN\n"
+		/* Rename the index, so that it will be dropped by
+		row_merge_drop_temp_indexes() at crash recovery
+		if the server crashes before this trx is committed. */
+		"UPDATE SYS_INDEXES SET NAME=CONCAT('"
+		TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
+		"COMMIT WORK;\n"
+		/* Drop the field definitions of the index. */
 		"DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
+		/* Drop the index definition and the B-tree. */
 		"DELETE FROM SYS_INDEXES WHERE ID = :indexid\n"
 		"		AND TABLE_ID = :tableid;\n"
 		"END;\n";
@@ -1909,6 +2067,7 @@ row_merge_file_create(
 {
 	merge_file->fd = innobase_mysql_tmpfile();
 	merge_file->offset = 0;
+	merge_file->n_rec = 0;
 }
 
 /*********************************************************************//**
@@ -2129,7 +2288,7 @@ row_merge_rename_tables(
 	if (err != DB_SUCCESS) {
 err_exit:
 		trx->error_state = DB_SUCCESS;
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		trx->error_state = DB_SUCCESS;
 	}
 

=== modified file 'storage/innodb_plugin/row/row0mysql.c'
--- a/storage/innodb_plugin/row/row0mysql.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/row/row0mysql.c	2009-10-09 12:52:18 +0000
@@ -510,7 +510,7 @@ handle_new_error:
 	switch (err) {
 	case DB_LOCK_WAIT_TIMEOUT:
 		if (row_rollback_on_timeout) {
-			trx_general_rollback_for_mysql(trx, FALSE, NULL);
+			trx_general_rollback_for_mysql(trx, NULL);
 			break;
 		}
 		/* fall through */
@@ -526,7 +526,7 @@ handle_new_error:
 			/* Roll back the latest, possibly incomplete
 			insertion or update */
 
-			trx_general_rollback_for_mysql(trx, TRUE, savept);
+			trx_general_rollback_for_mysql(trx, savept);
 		}
 		/* MySQL will roll back the latest SQL statement */
 		break;
@@ -548,7 +548,7 @@ handle_new_error:
 		/* Roll back the whole transaction; this resolution was added
 		to version 3.23.43 */
 
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		break;
 
 	case DB_MUST_GET_MORE_FILE_SPACE:
@@ -866,18 +866,22 @@ row_update_statistics_if_needed(
 }
 
 /*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
 UNIV_INTERN
 void
 row_unlock_table_autoinc_for_mysql(
 /*===============================*/
 	trx_t*	trx)	/*!< in/out: transaction */
 {
-	mutex_enter(&kernel_mutex);
+	if (lock_trx_holds_autoinc_locks(trx)) {
+		mutex_enter(&kernel_mutex);
 
-	lock_release_autoinc_locks(trx);
+		lock_release_autoinc_locks(trx);
 
-	mutex_exit(&kernel_mutex);
+		mutex_exit(&kernel_mutex);
+	}
 }
 
 /*********************************************************************//**
@@ -1767,7 +1771,6 @@ row_create_table_for_mysql(
 	const char*	table_name;
 	ulint		table_name_len;
 	ulint		err;
-	ulint		i;
 
 	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 #ifdef UNIV_SYNC_DEBUG
@@ -1802,15 +1805,6 @@ err_exit:
 		goto err_exit;
 	}
 
-	/* Check that no reserved column names are used. */
-	for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
-		if (dict_col_name_is_reserved(
-			    dict_table_get_col_name(table, i))) {
-
-			goto err_exit;
-		}
-	}
-
 	trx_start_if_not_started(trx);
 
 	/* The table name is prefixed with the database name and a '/'.
@@ -1885,7 +1879,7 @@ err_exit:
 
 	if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
 		trx->error_state = DB_SUCCESS;
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 	}
 
 	switch (err) {
@@ -2053,7 +2047,7 @@ error_handling:
 
 		trx->error_state = DB_SUCCESS;
 
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 
 		row_drop_table_for_mysql(table_name, trx, FALSE);
 
@@ -2121,7 +2115,7 @@ row_table_add_foreign_constraints(
 
 		trx->error_state = DB_SUCCESS;
 
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 
 		row_drop_table_for_mysql(name, trx, FALSE);
 
@@ -2488,7 +2482,7 @@ row_discard_tablespace_for_mysql(
 
 	if (err != DB_SUCCESS) {
 		trx->error_state = DB_SUCCESS;
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		trx->error_state = DB_SUCCESS;
 	} else {
 		dict_table_change_id_in_cache(table, new_id);
@@ -2497,7 +2491,7 @@ row_discard_tablespace_for_mysql(
 
 		if (!success) {
 			trx->error_state = DB_SUCCESS;
-			trx_general_rollback_for_mysql(trx, FALSE, NULL);
+			trx_general_rollback_for_mysql(trx, NULL);
 			trx->error_state = DB_SUCCESS;
 
 			err = DB_ERROR;
@@ -2949,7 +2943,7 @@ next_rec:
 
 	if (err != DB_SUCCESS) {
 		trx->error_state = DB_SUCCESS;
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		trx->error_state = DB_SUCCESS;
 		ut_print_timestamp(stderr);
 		fputs("  InnoDB: Unable to assign a new identifier to table ",
@@ -3590,7 +3584,7 @@ row_delete_constraint(
 
 	if ((err == DB_SUCCESS) && !strchr(id, '/')) {
 		/* Old format < 4.0.18 constraints have constraint ids
-		<number>_<number>. We only try deleting them if the
+		NUMBER_NUMBER. We only try deleting them if the
 		constraint name does not contain a '/' character, otherwise
 		deleting a new format constraint named 'foo/bar' from
 		database 'baz' would remove constraint 'bar' from database
@@ -3854,7 +3848,7 @@ end:
 			      "InnoDB: succeed.\n", stderr);
 		}
 		trx->error_state = DB_SUCCESS;
-		trx_general_rollback_for_mysql(trx, FALSE, NULL);
+		trx_general_rollback_for_mysql(trx, NULL);
 		trx->error_state = DB_SUCCESS;
 	} else {
 		/* The following call will also rename the .ibd data file if
@@ -3863,7 +3857,7 @@ end:
 		if (!dict_table_rename_in_cache(table, new_name,
 						!new_is_tmp)) {
 			trx->error_state = DB_SUCCESS;
-			trx_general_rollback_for_mysql(trx, FALSE, NULL);
+			trx_general_rollback_for_mysql(trx, NULL);
 			trx->error_state = DB_SUCCESS;
 			goto funct_exit;
 		}
@@ -3903,7 +3897,7 @@ end:
 			ut_a(dict_table_rename_in_cache(table,
 							old_name, FALSE));
 			trx->error_state = DB_SUCCESS;
-			trx_general_rollback_for_mysql(trx, FALSE, NULL);
+			trx_general_rollback_for_mysql(trx, NULL);
 			trx->error_state = DB_SUCCESS;
 		}
 	}

=== added file 'storage/innodb_plugin/scripts/export.sh'
--- a/storage/innodb_plugin/scripts/export.sh	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/scripts/export.sh	2009-10-12 12:56:02 +0000
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+# export current working directory in a format suitable for sending to MySQL
+# as a snapshot. also generates the actual snapshot and sends it to MySQL.
+
+set -eu
+
+die () {
+  echo $*
+  exit 1
+}
+
+if [ $# -ne 2 ] ; then
+  die "Usage: export.sh revision-number-of-last-snapshot current-revision-number"
+fi
+
+# If we are run from within the scripts/ directory then change directory to
+# one level up so that the relative paths work.
+DIR=`basename $PWD`
+
+if [ "${DIR}" = "scripts" ]; then
+  cd ..
+fi
+
+START_REV=$(($1 + 1))
+END_REV=$2
+
+set +u
+if test -z $EDITOR; then
+  die "\$EDITOR is not set"
+fi
+set -u
+
+rm -rf to-mysql
+mkdir to-mysql{,/storage,/patches,/mysql-test{,/t,/r,/include}}
+svn log -v -r "$START_REV:BASE" > to-mysql/log
+svn export -q . to-mysql/storage/innobase
+
+REV=$START_REV
+while [ $REV -le $END_REV ]
+do
+  PATCH=to-mysql/patches/r$REV.patch
+  svn log -v -r$REV > $PATCH
+  if [ $(wc -c < $PATCH) -gt 73 ]
+  then
+    svn diff -r$(($REV-1)):$REV >> $PATCH
+  else
+    rm $PATCH
+  fi
+  REV=$(($REV + 1))
+done
+
+cd to-mysql/storage/innobase
+
+mv mysql-test/*.test mysql-test/*.opt ../../mysql-test/t
+mv mysql-test/*.result ../../mysql-test/r
+mv mysql-test/*.inc ../../mysql-test/include
+rmdir mysql-test
+
+rm setup.sh export.sh revert_gen.sh compile-innodb-debug compile-innodb
+
+cd ../..
+$EDITOR log
+cd ..
+
+fname="innodb-5.1-ss$2.tar.gz"
+
+rm -f $fname
+tar czf $fname to-mysql
+scp $fname mysql:snapshots
+rm $fname
+rm -rf to-mysql
+
+echo "Sent $fname to MySQL"

=== modified file 'storage/innodb_plugin/srv/srv0srv.c'
--- a/storage/innodb_plugin/srv/srv0srv.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/srv/srv0srv.c	2009-10-09 12:19:13 +0000
@@ -102,6 +102,7 @@ Created 10/8/1995 Heikki Tuuri
 #include "row0mysql.h"
 #include "ha_prototypes.h"
 #include "trx0i_s.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
 
 /* This is set to TRUE if the MySQL user has set it in MySQL; currently
 affects only FOREIGN KEY definition parsing */
@@ -292,12 +293,6 @@ UNIV_INTERN ulint srv_buf_pool_flushed =
 reading of a disk page */
 UNIV_INTERN ulint srv_buf_pool_reads = 0;
 
-/** Number of sequential read-aheads */
-UNIV_INTERN ulint srv_read_ahead_seq = 0;
-
-/** Number of random read-aheads */
-UNIV_INTERN ulint srv_read_ahead_rnd = 0;
-
 /* structure to pass status variables to MySQL */
 UNIV_INTERN export_struc export_vars;
 
@@ -464,8 +459,6 @@ static ulint   srv_main_background_loops
 static ulint   srv_main_flush_loops		= 0;
 /* Log writes involving flush. */
 static ulint   srv_log_writes_and_flush		= 0;
-/* Log writes not including flush. */
-static ulint   srv_log_buffer_writes		= 0;
 
 /* This is only ever touched by the master thread. It records the
 time when the last flush of log file has happened. The master
@@ -614,7 +607,7 @@ future, but at the moment we plan to imp
 which could be called a global priority inheritance. If a thread
 has to wait for a long time, say 300 milliseconds, for a resource,
 we just guess that it may be waiting for a resource owned by a background
-thread, and boost the the priority of all runnable background threads
+thread, and boost the priority of all runnable background threads
 to the normal level. The background threads then themselves adjust
 their fixed priority back to background after releasing all resources
 they had (or, at some fixed points in their program code).
@@ -714,9 +707,8 @@ srv_print_master_thread_info(
 		srv_main_1_second_loops, srv_main_sleeps,
 		srv_main_10_second_loops, srv_main_background_loops,
 		srv_main_flush_loops);
-	fprintf(file, "srv_master_thread log flush and writes: %lu "
-		      " log writes only: %lu\n",
-		      srv_log_writes_and_flush, srv_log_buffer_writes);
+	fprintf(file, "srv_master_thread log flush and writes: %lu\n",
+		      srv_log_writes_and_flush);
 }
 
 /*********************************************************************//**
@@ -1877,14 +1869,16 @@ srv_export_innodb_status(void)
 	export_vars.innodb_data_reads = os_n_file_reads;
 	export_vars.innodb_data_writes = os_n_file_writes;
 	export_vars.innodb_data_written = srv_data_written;
-	export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
+	export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
 	export_vars.innodb_buffer_pool_write_requests
 		= srv_buf_pool_write_requests;
 	export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
 	export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
 	export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
-	export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
-	export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
+	export_vars.innodb_buffer_pool_read_ahead
+		= buf_pool->stat.n_ra_pages_read;
+	export_vars.innodb_buffer_pool_read_ahead_evicted
+		= buf_pool->stat.n_ra_pages_evicted;
 	export_vars.innodb_buffer_pool_pages_data
 		= UT_LIST_GET_LEN(buf_pool->LRU);
 	export_vars.innodb_buffer_pool_pages_dirty
@@ -1915,9 +1909,9 @@ srv_export_innodb_status(void)
 	export_vars.innodb_log_writes = srv_log_writes;
 	export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
 	export_vars.innodb_dblwr_writes = srv_dblwr_writes;
-	export_vars.innodb_pages_created = buf_pool->n_pages_created;
-	export_vars.innodb_pages_read = buf_pool->n_pages_read;
-	export_vars.innodb_pages_written = buf_pool->n_pages_written;
+	export_vars.innodb_pages_created = buf_pool->stat.n_pages_created;
+	export_vars.innodb_pages_read = buf_pool->stat.n_pages_read;
+	export_vars.innodb_pages_written = buf_pool->stat.n_pages_written;
 	export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
 	export_vars.innodb_row_lock_current_waits
 		= srv_n_lock_wait_current_count;
@@ -2284,12 +2278,6 @@ srv_sync_log_buffer_in_background(void)
 		log_buffer_sync_in_background(TRUE);
 		srv_last_log_flush_time = current_time;
 		srv_log_writes_and_flush++;
-	} else {
-		/* Actually we don't need to write logs here.
-		We are just being extra safe here by forcing
-		the log buffer to log file. */
-		log_buffer_sync_in_background(FALSE);
-		srv_log_buffer_writes++;
 	}
 }
 
@@ -2340,8 +2328,8 @@ loop:
 
 	srv_main_thread_op_info = "reserving kernel mutex";
 
-	n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
-		+ buf_pool->n_pages_written;
+	n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+		+ buf_pool->stat.n_pages_written;
 	mutex_enter(&kernel_mutex);
 
 	/* Store the user activity counter at the start of this loop */
@@ -2361,8 +2349,8 @@ loop:
 	skip_sleep = FALSE;
 
 	for (i = 0; i < 10; i++) {
-		n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
-			+ buf_pool->n_pages_written;
+		n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+			+ buf_pool->stat.n_pages_written;
 		srv_main_thread_op_info = "sleeping";
 		srv_main_1_second_loops++;
 
@@ -2401,8 +2389,8 @@ loop:
 
 		n_pend_ios = buf_get_n_pending_ios()
 			+ log_sys->n_pending_writes;
-		n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
-			+ buf_pool->n_pages_written;
+		n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+			+ buf_pool->stat.n_pages_written;
 		if (n_pend_ios < SRV_PEND_IO_THRESHOLD
 		    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
 			srv_main_thread_op_info = "doing insert buffer merge";
@@ -2418,6 +2406,8 @@ loop:
 			/* Try to keep the number of modified pages in the
 			buffer pool under the limit wished by the user */
 
+			srv_main_thread_op_info =
+				"flushing buffer pool pages";
 			n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 							  PCT_IO(100),
 							  IB_ULONGLONG_MAX);
@@ -2436,6 +2426,8 @@ loop:
 			ulint n_flush = buf_flush_get_desired_flush_rate();
 
 			if (n_flush) {
+				srv_main_thread_op_info =
+					"flushing buffer pool pages";
 				n_flush = ut_min(PCT_IO(100), n_flush);
 				n_pages_flushed =
 					buf_flush_batch(
@@ -2473,8 +2465,8 @@ loop:
 	are not required, and may be disabled. */
 
 	n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
-	n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
-		+ buf_pool->n_pages_written;
+	n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+		+ buf_pool->stat.n_pages_written;
 
 	srv_main_10_second_loops++;
 	if (n_pend_ios < SRV_PEND_IO_THRESHOLD

=== modified file 'storage/innodb_plugin/srv/srv0start.c'
--- a/storage/innodb_plugin/srv/srv0start.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/srv/srv0start.c	2009-10-12 12:00:56 +0000
@@ -103,6 +103,7 @@ Created 2/16/1996 Heikki Tuuri
 # include "row0row.h"
 # include "row0mysql.h"
 # include "btr0pcur.h"
+# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
 
 /** Log sequence number immediately after startup */
 UNIV_INTERN ib_uint64_t	srv_start_lsn;
@@ -1096,6 +1097,10 @@ innobase_start_or_create_for_mysql(void)
 		"InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
 #endif
 
+#ifdef UNIV_LOG_LSN_DEBUG
+	fprintf(stderr,
+		"InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
+#endif /* UNIV_LOG_LSN_DEBUG */
 #ifdef UNIV_MEM_DEBUG
 	fprintf(stderr,
 		"InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
@@ -1106,34 +1111,7 @@ innobase_start_or_create_for_mysql(void)
 			"InnoDB: The InnoDB memory heap is disabled\n");
 	}
 
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-	fprintf(stderr,
-		"InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
-# else /* INNODB_RW_LOCKS_USE_ATOMICS */
-	fprintf(stderr,
-		"InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif defined(HAVE_SOLARIS_ATOMICS)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-	fprintf(stderr,
-		"InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n");
-# else
-	fprintf(stderr,
-		"InnoDB: Mutexes use Solaris atomic functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif HAVE_WINDOWS_ATOMICS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-	fprintf(stderr,
-		"InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n");
-# else
-	fprintf(stderr,
-		"InnoDB: Mutexes use Windows interlocked functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#else /* HAVE_GCC_ATOMIC_BUILTINS */
-	fprintf(stderr,
-		"InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+	fprintf(stderr, "InnoDB: %s\n", IB_ATOMICS_STARTUP_MSG);
 
 	/* Since InnoDB does not currently clean up all its internal data
 	structures in MySQL Embedded Server Library server_end(), we
@@ -1829,7 +1807,7 @@ innobase_start_or_create_for_mysql(void)
 		/* Actually, we did not change the undo log format between
 		4.0 and 4.1.1, and we would not need to run purge to
 		completion. Note also that the purge algorithm in 4.1.1
-		can process the the history list again even after a full
+		can process the history list again even after a full
 		purge, because our algorithm does not cut the end of the
 		history list in all cases so that it would become empty
 		after a full purge. That mean that we may purge 4.0 type

=== modified file 'storage/innodb_plugin/sync/sync0rw.c'
--- a/storage/innodb_plugin/sync/sync0rw.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/sync/sync0rw.c	2009-10-09 12:19:13 +0000
@@ -38,6 +38,7 @@ Created 9/11/1995 Heikki Tuuri
 #include "os0thread.h"
 #include "mem0mem.h"
 #include "srv0srv.h"
+#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
 
 /*
 	IMPLEMENTATION OF THE RW_LOCK

=== modified file 'storage/innodb_plugin/sync/sync0sync.c'
--- a/storage/innodb_plugin/sync/sync0sync.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/sync/sync0sync.c	2009-10-12 12:00:56 +0000
@@ -39,6 +39,7 @@ Created 9/5/1995 Heikki Tuuri
 #include "buf0buf.h"
 #include "srv0srv.h"
 #include "buf0types.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
 
 /*
 	REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -849,7 +850,8 @@ sync_thread_levels_g(
 /*=================*/
 	sync_level_t*	arr,	/*!< in: pointer to level array for an OS
 				thread */
-	ulint		limit)	/*!< in: level limit */
+	ulint		limit,	/*!< in: level limit */
+	ulint		warn)	/*!< in: TRUE=display a diagnostic message */
 {
 	sync_level_t*	slot;
 	rw_lock_t*	lock;
@@ -863,6 +865,11 @@ sync_thread_levels_g(
 		if (slot->latch != NULL) {
 			if (slot->level <= limit) {
 
+				if (!warn) {
+
+					return(FALSE);
+				}
+
 				lock = slot->latch;
 				mutex = slot->latch;
 
@@ -1100,7 +1107,7 @@ sync_thread_add_level(
 	case SYNC_DICT_HEADER:
 	case SYNC_TRX_I_S_RWLOCK:
 	case SYNC_TRX_I_S_LAST_READ:
-		if (!sync_thread_levels_g(array, level)) {
+		if (!sync_thread_levels_g(array, level, TRUE)) {
 			fprintf(stderr,
 				"InnoDB: sync_thread_levels_g(array, %lu)"
 				" does not hold!\n", level);
@@ -1111,36 +1118,44 @@ sync_thread_add_level(
 		/* Either the thread must own the buffer pool mutex
 		(buf_pool_mutex), or it is allowed to latch only ONE
 		buffer block (block->mutex or buf_pool_zip_mutex). */
-		if (!sync_thread_levels_g(array, level)) {
-			ut_a(sync_thread_levels_g(array, level - 1));
+		if (!sync_thread_levels_g(array, level, FALSE)) {
+			ut_a(sync_thread_levels_g(array, level - 1, TRUE));
 			ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
 		}
 		break;
 	case SYNC_REC_LOCK:
-		ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
-		      && sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
-		     || sync_thread_levels_g(array, SYNC_REC_LOCK));
+		if (sync_thread_levels_contain(array, SYNC_KERNEL)) {
+			ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK - 1,
+						  TRUE));
+		} else {
+			ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK, TRUE));
+		}
 		break;
 	case SYNC_IBUF_BITMAP:
 		/* Either the thread must own the master mutex to all
 		the bitmap pages, or it is allowed to latch only ONE
 		bitmap page. */
-		ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
-		      && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
-		     || sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
+		if (sync_thread_levels_contain(array,
+					       SYNC_IBUF_BITMAP_MUTEX)) {
+			ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1,
+						  TRUE));
+		} else {
+			ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
+						  TRUE));
+		}
 		break;
 	case SYNC_FSP_PAGE:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP));
 		break;
 	case SYNC_FSP:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP)
-		     || sync_thread_levels_g(array, SYNC_FSP));
+		     || sync_thread_levels_g(array, SYNC_FSP, TRUE));
 		break;
 	case SYNC_TRX_UNDO_PAGE:
 		ut_a(sync_thread_levels_contain(array, SYNC_TRX_UNDO)
 		     || sync_thread_levels_contain(array, SYNC_RSEG)
 		     || sync_thread_levels_contain(array, SYNC_PURGE_SYS)
-		     || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE));
+		     || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE, TRUE));
 		break;
 	case SYNC_RSEG_HEADER:
 		ut_a(sync_thread_levels_contain(array, SYNC_RSEG));
@@ -1152,37 +1167,41 @@ sync_thread_add_level(
 	case SYNC_TREE_NODE:
 		ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
 		     || sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
-		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
 		break;
 	case SYNC_TREE_NODE_NEW:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
 		     || sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
 		break;
 	case SYNC_INDEX_TREE:
-		ut_a((sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
-		      && sync_thread_levels_contain(array, SYNC_FSP)
-		      && sync_thread_levels_g(array, SYNC_FSP_PAGE - 1))
-		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+		if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
+		    && sync_thread_levels_contain(array, SYNC_FSP)) {
+			ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1,
+						  TRUE));
+		} else {
+			ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
+						  TRUE));
+		}
 		break;
 	case SYNC_IBUF_MUTEX:
-		ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1));
+		ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
 		break;
 	case SYNC_IBUF_PESS_INSERT_MUTEX:
-		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
-		     && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+		ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
 		break;
 	case SYNC_IBUF_HEADER:
-		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
-		     && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
-		     && !sync_thread_levels_contain(
-			     array, SYNC_IBUF_PESS_INSERT_MUTEX));
+		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+		ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+		ut_a(!sync_thread_levels_contain(array,
+						 SYNC_IBUF_PESS_INSERT_MUTEX));
 		break;
 	case SYNC_DICT:
 #ifdef UNIV_DEBUG
 		ut_a(buf_debug_prints
-		     || sync_thread_levels_g(array, SYNC_DICT));
+		     || sync_thread_levels_g(array, SYNC_DICT, TRUE));
 #else /* UNIV_DEBUG */
-		ut_a(sync_thread_levels_g(array, SYNC_DICT));
+		ut_a(sync_thread_levels_g(array, SYNC_DICT, TRUE));
 #endif /* UNIV_DEBUG */
 		break;
 	default:

=== modified file 'storage/innodb_plugin/thr/thr0loc.c'
--- a/storage/innodb_plugin/thr/thr0loc.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/thr/thr0loc.c	2009-10-08 10:00:49 +0000
@@ -62,7 +62,7 @@ struct thr_local_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 the thread is doing an ibuf
+	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) */

=== modified file 'storage/innodb_plugin/trx/trx0rec.c'
--- a/storage/innodb_plugin/trx/trx0rec.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/trx/trx0rec.c	2009-10-08 10:00:49 +0000
@@ -1333,7 +1333,7 @@ trx_undo_get_undo_rec_low(
 	ulint		rseg_id;
 	ulint		page_no;
 	ulint		offset;
-	page_t*		undo_page;
+	const page_t*	undo_page;
 	trx_rseg_t*	rseg;
 	ibool		is_insert;
 	mtr_t		mtr;
@@ -1572,7 +1572,7 @@ trx_undo_prev_version_build(
 
 		/* We have to set the appropriate extern storage bits in the
 		old version of the record: the extern bits in rec for those
-		fields that update does NOT update, as well as the the bits for
+		fields that update does NOT update, as well as the bits for
 		those fields that update updates to become externally stored
 		fields. Store the info: */
 

=== modified file 'storage/innodb_plugin/trx/trx0roll.c'
--- a/storage/innodb_plugin/trx/trx0roll.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/trx/trx0roll.c	2009-10-08 13:05:59 +0000
@@ -66,9 +66,9 @@ int
 trx_general_rollback_for_mysql(
 /*===========================*/
 	trx_t*		trx,	/*!< in: transaction handle */
-	ibool		partial,/*!< in: TRUE if partial rollback requested */
 	trx_savept_t*	savept)	/*!< in: pointer to savepoint undo number, if
-				partial rollback requested */
+				partial rollback requested, or NULL for
+				complete rollback */
 {
 	mem_heap_t*	heap;
 	que_thr_t*	thr;
@@ -85,9 +85,8 @@ trx_general_rollback_for_mysql(
 
 	roll_node = roll_node_create(heap);
 
-	roll_node->partial = partial;
-
-	if (partial) {
+	if (savept) {
+		roll_node->partial = TRUE;
 		roll_node->savept = *savept;
 	}
 
@@ -145,7 +144,7 @@ trx_rollback_for_mysql(
 	the transaction object does not have an InnoDB session object, and we
 	set a dummy session that we use for all MySQL transactions. */
 
-	err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+	err = trx_general_rollback_for_mysql(trx, NULL);
 
 	trx->op_info = "";
 
@@ -170,8 +169,7 @@ trx_rollback_last_sql_stat_for_mysql(
 
 	trx->op_info = "rollback of SQL statement";
 
-	err = trx_general_rollback_for_mysql(trx, TRUE,
-					     &(trx->last_sql_stat_start));
+	err = trx_general_rollback_for_mysql(trx, &trx->last_sql_stat_start);
 	/* The following call should not be needed, but we play safe: */
 	trx_mark_sql_stat_end(trx);
 
@@ -282,7 +280,7 @@ trx_rollback_to_savepoint_for_mysql(
 
 	trx->op_info = "rollback to a savepoint";
 
-	err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+	err = trx_general_rollback_for_mysql(trx, &savep->savept);
 
 	/* Store the current undo_no of the transaction so that we know where
 	to roll back if we have to roll back the next SQL statement: */
@@ -534,28 +532,26 @@ trx_rollback_active(
 Rollback or clean up any incomplete transactions which were
 encountered in crash recovery.  If the transaction already was
 committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread.
-@return	a dummy parameter */
+transaction was not yet committed, then we roll it back. */
 UNIV_INTERN
-os_thread_ret_t
-trx_rollback_or_clean_all_recovered(
-/*================================*/
-	void*	arg __attribute__((unused)))
-			/*!< in: a dummy parameter required by
-			os_thread_create */
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+	ibool	all)	/*!< in: FALSE=roll back dictionary transactions;
+			TRUE=roll back all non-PREPARED transactions */
 {
 	trx_t*	trx;
 
 	mutex_enter(&kernel_mutex);
 
-	if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+	if (!UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+		goto leave_function;
+	}
 
+	if (all) {
 		fprintf(stderr,
 			"InnoDB: Starting in background the rollback"
 			" of uncommitted transactions\n");
-	} else {
-		goto leave_function;
 	}
 
 	mutex_exit(&kernel_mutex);
@@ -584,18 +580,42 @@ loop:
 			goto loop;
 
 		case TRX_ACTIVE:
-			mutex_exit(&kernel_mutex);
-			trx_rollback_active(trx);
-			goto loop;
+			if (all || trx_get_dict_operation(trx)
+			    != TRX_DICT_OP_NONE) {
+				mutex_exit(&kernel_mutex);
+				trx_rollback_active(trx);
+				goto loop;
+			}
 		}
 	}
 
-	ut_print_timestamp(stderr);
-	fprintf(stderr,
-		"  InnoDB: Rollback of non-prepared transactions completed\n");
+	if (all) {
+		ut_print_timestamp(stderr);
+		fprintf(stderr,
+			"  InnoDB: Rollback of non-prepared"
+			" transactions completed\n");
+	}
 
 leave_function:
 	mutex_exit(&kernel_mutex);
+}
+
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery.  If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back.
+Note: this is done in a background thread.
+@return	a dummy parameter */
+UNIV_INTERN
+os_thread_ret_t
+trx_rollback_or_clean_all_recovered(
+/*================================*/
+	void*	arg __attribute__((unused)))
+			/*!< in: a dummy parameter required by
+			os_thread_create */
+{
+	trx_rollback_or_clean_recovered(TRUE);
 
 	/* We count the number of threads in os_thread_exit(). A created
 	thread should always use that to exit and not use return() to exit. */

=== modified file 'storage/innodb_plugin/trx/trx0trx.c'
--- a/storage/innodb_plugin/trx/trx0trx.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/trx/trx0trx.c	2009-10-09 14:13:15 +0000
@@ -803,7 +803,7 @@ trx_commit_off_kernel(
 		in exactly the same order as commit lsn's, if the transactions
 		have different rollback segments. To get exactly the same
 		order we should hold the kernel mutex up to this point,
-		adding to to the contention of the kernel mutex. However, if
+		adding to the contention of the kernel mutex. However, if
 		a transaction T2 is able to see modifications made by
 		a transaction T1, T2 will always get a bigger transaction
 		number and a bigger commit lsn than T1. */
@@ -950,7 +950,7 @@ trx_commit_off_kernel(
 /****************************************************************//**
 Cleans up a transaction at database startup. The cleanup is needed if
 the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
 UNIV_INTERN
 void
 trx_cleanup_at_db_startup(

=== modified file 'storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c'
--- a/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c	2009-10-08 13:05:59 +0000
@@ -17,18 +17,38 @@ Place, Suite 330, Boston, MA 02111-1307 
 *****************************************************************************/
 
 /*****************************************************************************
-If this program compiles, then pthread_t objects can be used as arguments
-to Solaris libc atomic functions.
+If this program compiles and returns 0, then pthread_t objects can be used as
+arguments to Solaris libc atomic functions.
 
 Created April 18, 2009 Vasil Dimov
 *****************************************************************************/
 
 #include <pthread.h>
+#include <string.h>
 
 int
 main(int argc, char** argv)
 {
-	pthread_t	x = 0;
+	pthread_t	x1;
+	pthread_t	x2;
+	pthread_t	x3;
+
+	memset(&x1, 0x0, sizeof(x1));
+	memset(&x2, 0x0, sizeof(x2));
+	memset(&x3, 0x0, sizeof(x3));
+
+	if (sizeof(pthread_t) == 4) {
+
+		atomic_cas_32(&x1, x2, x3);
+
+	} else if (sizeof(pthread_t) == 8) {
+
+		atomic_cas_64(&x1, x2, x3);
+
+	} else {
+
+		return(1);
+	}
 
 	return(0);
 }

=== added file 'storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c'
--- a/storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c	1970-01-01 00:00:00 +0000
+++ b/storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c	2009-10-12 12:00:56 +0000
@@ -0,0 +1,61 @@
+/*****************************************************************************
+
+Copyright (c) 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
+
+*****************************************************************************/
+
+/*****************************************************************************
+If this program compiles and returns 0, then GCC atomic funcions are available.
+
+Created September 12, 2009 Vasil Dimov
+*****************************************************************************/
+
+int
+main(int argc, char** argv)
+{
+	long	x;
+	long	y;
+	long	res;
+	char	c;
+
+	x = 10;
+	y = 123;
+	res = __sync_bool_compare_and_swap(&x, x, y);
+	if (!res || x != y) {
+		return(1);
+	}
+
+	x = 10;
+	y = 123;
+	res = __sync_bool_compare_and_swap(&x, x + 1, y);
+	if (res || x != 10) {
+		return(1);
+	}
+
+	x = 10;
+	y = 123;
+	res = __sync_add_and_fetch(&x, y);
+	if (res != 123 + 10 || x != 123 + 10) {
+		return(1);
+	}
+
+	c = 10;
+	res = __sync_lock_test_and_set(&c, 123);
+	if (res != 10 || c != 123) {
+		return(1);
+	}
+
+	return(0);
+}

=== modified file 'storage/innodb_plugin/ut/ut0ut.c'
--- a/storage/innodb_plugin/ut/ut0ut.c	2009-07-30 12:42:56 +0000
+++ b/storage/innodb_plugin/ut/ut0ut.c	2009-10-08 12:52:21 +0000
@@ -132,6 +132,7 @@ ut_time(void)
 	return(time(NULL));
 }
 
+#ifndef UNIV_HOTBACKUP
 /**********************************************************//**
 Returns system time.
 Upon successful completion, the value 0 is returned; otherwise the
@@ -200,6 +201,24 @@ ut_time_us(
 }
 
 /**********************************************************//**
+Returns the number of milliseconds since some epoch.  The
+value may wrap around.  It should only be used for heuristic
+purposes.
+@return	ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void)
+/*============*/
+{
+	struct timeval	tv;
+
+	ut_gettimeofday(&tv, NULL);
+
+	return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+#endif /* !UNIV_HOTBACKUP */
+
+/**********************************************************//**
 Returns the difference of two times in seconds.
 @return	time2 - time1 expressed in seconds */
 UNIV_INTERN

=== removed directory 'storage/innodb_plugin/win-plugin'
=== removed file 'storage/innodb_plugin/win-plugin/README'
--- a/storage/innodb_plugin/win-plugin/README	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/win-plugin/README	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-This directory contains patches that need to be applied to the MySQL
-source tree in order to build the dynamic plugin on Windows --
-HA_INNODB.DLL. Please note the followings when adding the patches:
-
-* The patch must be applied from the mysql top-level source directory.
-  patch -p0 < win-plugin.diff
-* The patch filenames end in ".diff".
-* All patches here are expected to apply cleanly to the latest MySQL 5.1
-  tree when storage/innobase is replaced with this InnoDB branch.
-
-When applying the patch, the following files will be modified:
-
-  * CMakeLists.txt
-  * sql/CMakeLists.txt
-  * win/configure.js
-
-Also, two new files will be added:
-
-  * sql/mysqld.def
-  * sql/mysqld_x64.def
-
-You can get "patch" utility for Windows from http://unxutils.sourceforge.net/

=== removed file 'storage/innodb_plugin/win-plugin/win-plugin.diff'
--- a/storage/innodb_plugin/win-plugin/win-plugin.diff	2009-05-27 09:45:59 +0000
+++ b/storage/innodb_plugin/win-plugin/win-plugin.diff	1970-01-01 00:00:00 +0000
@@ -1,279 +0,0 @@
-diff -Nur CMakeLists.txt.orig CMakeLists.txt
---- CMakeLists.txt.orig	2008-10-03 12:25:41 -05:00
-+++ CMakeLists.txt	2008-09-26 17:32:51 -05:00
-@@ -254,9 +254,9 @@
- IF(WITH_FEDERATED_STORAGE_ENGINE)
-   ADD_SUBDIRECTORY(storage/federated)
- ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
--IF(WITH_INNOBASE_STORAGE_ENGINE)
-+IF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
-   ADD_SUBDIRECTORY(storage/innobase)
--ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
-+ENDIF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(sql)
- ADD_SUBDIRECTORY(server-tools/instance-manager)
- ADD_SUBDIRECTORY(libmysql)
- 
-diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
---- sql/CMakeLists.txt.orig	2008-10-03 12:25:41 -05:00
-+++ sql/CMakeLists.txt	2008-09-24 03:58:19 -05:00
-@@ -98,6 +98,15 @@
-                       LINK_FLAGS  "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
- ENDIF(cmake_version EQUAL 20406)
- 
-+# Checks for 64-bit version
-+IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+                      LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld_x64.def\"")
-+ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+                      LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld.def\"")
-+ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+
- IF(EMBED_MANIFESTS)
-   MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
- ENDIF(EMBED_MANIFESTS)
-
-diff -Nur sql/mysqld.def.orig sql/mysqld.def
---- sql/mysqld.def.orig	1969-12-31 18:00:00 -06:00
-+++ sql/mysqld.def	2009-04-09 02:20:32 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+	?use_hidden_primary_key@handler@@UAEXXZ
-+	?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
-+	?read_first_row@handler@@UAEHPAEI@Z
-+	?read_range_next@handler@@UAEHXZ
-+	?read_range_first@handler@@UAEHPBUst_key_range@@0_N1@Z
-+	?read_multi_range_first@handler@@UAEHPAPAUst_key_multi_range@@PAU2@I_NPAUst_handler_buffer@@@Z
-+	?read_multi_range_next@handler@@UAEHPAPAUst_key_multi_range@@@Z
-+	?index_read_idx_map@handler@@UAEHPAEIPBEKW4ha_rkey_function@@@Z
-+	?print_error@handler@@UAEXHH@Z
-+	?clone@handler@@UAEPAV1@PAUst_mem_root@@@Z
-+	?get_auto_increment@handler@@UAEX_K00PA_K1@Z
-+	?index_next_same@handler@@UAEHPAEPBEI@Z
-+	?get_error_message@handler@@UAE_NHPAVString@@@Z
-+	?ha_thd@handler@@IBEPAVTHD@@XZ
-+	?update_auto_increment@handler@@QAEHXZ
-+	?ha_statistic_increment@handler@@IBEXPQsystem_status_var@@K@Z
-+	?trans_register_ha@@YAXPAVTHD@@_NPAUhandlerton@@@Z
-+	?cmp@Field_blob@@QAEHPBEI0I@Z
-+	?set_time@Field_timestamp@@QAEXXZ
-+	?sql_print_error@@YAXPBDZZ
-+	?sql_print_warning@@YAXPBDZZ
-+	?check_global_access@@YA_NPAVTHD@@K@Z
-+	?schema_table_store_record@@YA_NPAVTHD@@PAUst_table@@@Z
-+	?get_quote_char_for_identifier@@YAHPAVTHD@@PBDI@Z
-+	?copy@String@@QAE_NXZ
-+	?copy@String@@QAE_NABV1@@Z
-+	?copy@String@@QAE_NPBDIPAUcharset_info_st@@@Z
-+	?copy_and_convert@@YAIPADIPAUcharset_info_st@@PBDI1PAI@Z
-+	?filename_to_tablename@@YAIPBDPADI@Z
-+	?strconvert@@YAIPAUcharset_info_st@@PBD0PADIPAI@Z
-+	?calculate_key_len@@YAIPAUst_table@@IPBEK@Z
-+	?sql_alloc@@YAPAXI@Z
-+	?localtime_to_TIME@@YAXPAUst_mysql_time@@PAUtm@@@Z
-+	?push_warning@@YAPAVMYSQL_ERROR@@PAVTHD@@W4enum_warning_level@1@IPBD@Z
-+	?push_warning_printf@@YAXPAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPBDZZ
-+	?drop_table@handler@@EAEXPBD@Z
-+	?column_bitmaps_signal@handler@@UAEXXZ
-+	?delete_table@handler@@MAEHPBD@Z
-+	?rename_table@handler@@MAEHPBD0@Z
-+	?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+	?THR_THD@@3PAVTHD@@A
-+	?end_of_list@@3Ulist_node@@A
-+	?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+	mysql_query_cache_invalidate4
-+	thd_query
-+	thd_sql_command
-+	thd_get_thread_id
-+	thd_get_xid
-+	thd_slave_thread
-+	thd_non_transactional_update
-+	thd_mark_transaction_to_rollback
-+	thd_security_context
-+	thd_charset
-+	thd_test_options
-+	thd_ha_data
-+	thd_killed
-+	thd_tx_isolation
-+	thd_tablespace_op
-+	thd_sql_command
-+	thd_memdup
-+	thd_make_lex_string
-+	thd_in_lock_tables
-+	thd_binlog_format
-+	_my_hash_init
-+	my_hash_free
-+	my_tmpdir
-+	check_if_legal_filename
-+	my_filename
-+	my_sync_dir_by_file
-+	alloc_root
-+	thr_lock_data_init
-+	thr_lock_init
-+	thr_lock_delete
-+	my_multi_malloc
-+	get_charset
-+	unpack_filename
-+	my_hash_insert
-+	my_hash_search
-+	my_hash_delete
-+	mysql_bin_log_file_pos
-+	mysql_bin_log_file_name
-+	mysqld_embedded
-+	my_thread_name
-+	my_malloc
-+	my_no_flags_free
-+	_sanity
-+	_mymalloc
-+	_myfree
-+	_my_strdup
-+	_my_thread_var
-+	my_error
-+	pthread_cond_init
-+	pthread_cond_signal
-+	pthread_cond_wait
-+	pthread_cond_destroy
-+	localtime_r
-+	my_strdup
-+	deflate
-+	deflateEnd
-+	deflateReset
-+	deflateInit2_
-+	inflateEnd
-+	inflateInit_
-+	inflate
-+	compressBound
-+	inflateInit2_
-+	adler32
-+	longlong2str
-+	strend
-+	my_snprintf
-
-diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
---- sql/mysqld_x64.def.orig	1969-12-31 18:00:00 -06:00
-+++ sql/mysqld_x64.def		2009-04-09 02:22:04 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+	?use_hidden_primary_key@handler@@UEAAXXZ
-+	?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
-+	?read_first_row@handler@@UEAAHPEAEI@Z
-+	?read_range_next@handler@@UEAAHXZ
-+	?read_range_first@handler@@UEAAHPEBUst_key_range@@0_N1@Z
-+	?read_multi_range_first@handler@@UEAAHPEAPEAUst_key_multi_range@@PEAU2@I_NPEAUst_handler_buffer@@@Z
-+	?read_multi_range_next@handler@@UEAAHPEAPEAUst_key_multi_range@@@Z
-+	?index_read_idx_map@handler@@UEAAHPEAEIPEBEKW4ha_rkey_function@@@Z
-+	?print_error@handler@@UEAAXHH@Z
-+	?clone@handler@@UEAAPEAV1@PEAUst_mem_root@@@Z
-+	?get_auto_increment@handler@@UEAAX_K00PEA_K1@Z
-+	?index_next_same@handler@@UEAAHPEAEPEBEI@Z
-+	?get_error_message@handler@@UEAA_NHPEAVString@@@Z
-+	?ha_thd@handler@@IEBAPEAVTHD@@XZ
-+	?update_auto_increment@handler@@QEAAHXZ
-+	?ha_statistic_increment@handler@@IEBAXPEQsystem_status_var@@K@Z
-+	?trans_register_ha@@YAXPEAVTHD@@_NPEAUhandlerton@@@Z
-+	?cmp@Field_blob@@QEAAHPEBEI0I@Z
-+	?set_time@Field_timestamp@@QEAAXXZ
-+	?sql_print_error@@YAXPEBDZZ
-+	?sql_print_warning@@YAXPEBDZZ
-+	?check_global_access@@YA_NPEAVTHD@@K@Z
-+	?schema_table_store_record@@YA_NPEAVTHD@@PEAUst_table@@@Z
-+	?get_quote_char_for_identifier@@YAHPEAVTHD@@PEBDI@Z
-+	?copy@String@@QEAA_NXZ
-+	?copy@String@@QEAA_NAEBV1@@Z
-+	?copy@String@@QEAA_NPEBDIPEAUcharset_info_st@@@Z
-+	?copy_and_convert@@YAIPEADIPEAUcharset_info_st@@PEBDI1PEAI@Z
-+	?filename_to_tablename@@YAIPEBDPEADI@Z
-+	?strconvert@@YAIPEAUcharset_info_st@@PEBD0PEADIPEAI@Z
-+	?calculate_key_len@@YAIPEAUst_table@@IPEBEK@Z
-+	?sql_alloc@@YAPEAX_K@Z
-+	?localtime_to_TIME@@YAXPEAUst_mysql_time@@PEAUtm@@@Z
-+	?push_warning@@YAPEAVMYSQL_ERROR@@PEAVTHD@@W4enum_warning_level@1@IPEBD@Z
-+	?push_warning_printf@@YAXPEAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPEBDZZ
-+	?drop_table@handler@@EEAAXPEBD@Z
-+	?column_bitmaps_signal@handler@@UEAAXXZ
-+	?delete_table@handler@@MEAAHPEBD@Z
-+	?rename_table@handler@@MEAAHPEBD0@Z
-+	?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+	?THR_THD@@3PEAVTHD@@EA
-+	?end_of_list@@3Ulist_node@@A
-+	?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+	mysql_query_cache_invalidate4
-+	thd_query
-+	thd_sql_command
-+	thd_get_thread_id
-+	thd_get_xid
-+	thd_slave_thread
-+	thd_non_transactional_update
-+	thd_mark_transaction_to_rollback
-+	thd_security_context
-+	thd_charset
-+	thd_test_options
-+	thd_ha_data
-+	thd_killed
-+	thd_tx_isolation
-+	thd_tablespace_op
-+	thd_sql_command
-+	thd_memdup
-+	thd_make_lex_string
-+	thd_in_lock_tables
-+	thd_binlog_format
-+	_my_hash_init
-+	my_hash_free
-+	my_tmpdir
-+	check_if_legal_filename
-+	my_filename
-+	my_sync_dir_by_file
-+	alloc_root
-+	thr_lock_data_init
-+	thr_lock_init
-+	thr_lock_delete
-+	my_multi_malloc
-+	get_charset
-+	unpack_filename
-+	my_hash_insert
-+	my_hash_search
-+	my_hash_delete
-+	mysql_bin_log_file_pos
-+	mysql_bin_log_file_name
-+	mysqld_embedded
-+	my_thread_name
-+	my_malloc
-+	my_no_flags_free
-+	_sanity
-+	_mymalloc
-+	_myfree
-+	_my_strdup
-+	_my_thread_var
-+	my_error
-+	pthread_cond_init
-+	pthread_cond_signal
-+	pthread_cond_wait
-+	pthread_cond_destroy
-+	localtime_r
-+	my_strdup
-+	deflate
-+	deflateEnd
-+	deflateReset
-+	deflateInit2_
-+	inflateEnd
-+	inflateInit_
-+	inflate
-+	compressBound
-+	inflateInit2_
-+	adler32
-+	longlong2str
-+	strend
-+	my_snprintf
-
-diff -Nur win/configure.js.orig win/configure.js
---- win/configure.js.orig	2008-09-26 21:18:37 -05:00
-+++ win/configure.js	2008-10-01 11:21:27 -05:00
-@@ -50,6 +50,7 @@
-             case "EMBED_MANIFESTS":
-             case "EXTRA_DEBUG":
-             case "WITH_EMBEDDED_SERVER":
-+            case "INNODB_DYNAMIC_PLUGIN":
-                     configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
-                     break;
-             case "MYSQL_SERVER_SUFFIX":


Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20091013082428-jpbyf58xdmz50x2c.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:3163) Dao-Gang.Qu13 Oct