[packages/percona-server/v5.1.x: 10/21] - up to 5.1.57

glen glen at pld-linux.org
Wed Oct 21 16:08:59 CEST 2015


commit 775c9bb6002d6704c4fc4d850c3525da6f370634
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Mon Jun 13 07:02:42 2011 +0000

    - up to 5.1.57
    
    Changed files:
        mysql-bug580324.patch -> 1.1.2.2
        mysql-bugfix48929.patch -> 1.1.2.2
        mysql-control_online_alter_index.patch -> 1.1.2.2
        mysql-fix-bug671764.patch -> 1.1.2.2
        mysql-i_s_innodb_buffer_pool_pages.patch -> 1.1.2.3
        mysql-innodb_adjust_defaults.patch -> 1.1.2.3
        mysql-innodb_admin_command_base.patch -> 1.1.2.3
        mysql-innodb_buffer_pool_shm.patch -> 1.1.2.3
        mysql-innodb_bug60788.patch -> 1.1.2.1
        mysql-innodb_deadlock_count.patch -> 1.1.2.4
        mysql-innodb_expand_fast_index_creation.patch -> 1.1.2.1
        mysql-innodb_expand_import.patch -> 1.1.2.4
        mysql-innodb_expand_undo_slots.patch -> 1.1.2.3
        mysql-innodb_fast_checksum.patch -> 1.1.2.4
        mysql-innodb_fast_shutdown.patch -> 1.1.2.2
        mysql-innodb_files_extend.patch -> 1.1.2.4
        mysql-innodb_fix_misc.patch -> 1.1.2.5
        mysql-innodb_lru_dump_restore.patch -> 1.1.2.4
        mysql-innodb_opt_lru_count.patch -> 1.1.2.2
        mysql-innodb_overwrite_relay_log_info.patch -> 1.1.2.3
        mysql-innodb_pass_corrupt_table.patch -> 1.1.2.4
        mysql-innodb_purge_thread.patch -> 1.1.2.3
        mysql-innodb_separate_doublewrite.patch -> 1.1.2.4
        mysql-innodb_show_enhancements.patch -> 1.1.2.3
        mysql-innodb_show_lock_name.patch -> 1.1.2.3
        mysql-innodb_show_status.patch -> 1.1.2.3
        mysql-innodb_show_sys_tables.patch -> 1.1.2.3
        mysql-innodb_stats.patch -> 1.1.2.3
        mysql-innodb_swap_builtin_plugin.patch -> 1.1.2.4
        mysql-log_connection_error.patch -> 1.1.2.2
        mysql-mysql-syslog.patch -> 1.1.2.2
        mysql-mysql_remove_eol_carret.patch -> 1.1.2.2
        mysql-optimizer_fix.patch -> 1.1.2.3
        mysql-query_cache_enhance.patch -> 1.1.2.3
        mysql-response-time-distribution.patch -> 1.1.2.2
        mysql-show_slave_status_nolock.patch -> 1.1.2.2
        mysql-show_temp_51.patch -> 1.1.2.3
        mysql-slow_extended.patch -> 1.1.2.3
        mysql-sql_no_fcache.patch -> 1.1.2.2
        mysql-suppress_log_warning_1592.patch -> 1.1.2.3

 mysql-bug580324.patch                         |   6 +-
 mysql-bugfix48929.patch                       |  10 +-
 mysql-control_online_alter_index.patch        |  12 +-
 mysql-fix-bug671764.patch                     |  10 +-
 mysql-i_s_innodb_buffer_pool_pages.patch      |   8 +-
 mysql-innodb_adjust_defaults.patch            |  12 +-
 mysql-innodb_admin_command_base.patch         |   4 +-
 mysql-innodb_buffer_pool_shm.patch            |   8 +-
 mysql-innodb_bug60788.patch                   | 124 ++++
 mysql-innodb_deadlock_count.patch             |   8 +-
 mysql-innodb_expand_fast_index_creation.patch | 742 ++++++++++++++++++++
 mysql-innodb_expand_import.patch              |  12 +-
 mysql-innodb_expand_undo_slots.patch          |   6 +-
 mysql-innodb_fast_checksum.patch              |  10 +-
 mysql-innodb_fast_shutdown.patch              |  16 +-
 mysql-innodb_files_extend.patch               |  18 +-
 mysql-innodb_fix_misc.patch                   |  47 +-
 mysql-innodb_lru_dump_restore.patch           |  28 +-
 mysql-innodb_opt_lru_count.patch              |  18 +-
 mysql-innodb_overwrite_relay_log_info.patch   |  10 +-
 mysql-innodb_pass_corrupt_table.patch         | 124 ++--
 mysql-innodb_purge_thread.patch               |  28 +-
 mysql-innodb_separate_doublewrite.patch       |  18 +-
 mysql-innodb_show_enhancements.patch          |   2 +-
 mysql-innodb_show_lock_name.patch             |  22 +-
 mysql-innodb_show_status.patch                |  16 +-
 mysql-innodb_show_sys_tables.patch            |  60 +-
 mysql-innodb_stats.patch                      | 952 +++++++++-----------------
 mysql-innodb_swap_builtin_plugin.patch        |   3 +-
 mysql-log_connection_error.patch              |   6 +-
 mysql-mysql-syslog.patch                      |  18 +-
 mysql-mysql_remove_eol_carret.patch           |  12 +-
 mysql-optimizer_fix.patch                     |  12 +-
 mysql-query_cache_enhance.patch               |  20 +-
 mysql-response-time-distribution.patch        |  32 +-
 mysql-show_slave_status_nolock.patch          |   6 +-
 mysql-show_temp_51.patch                      |  14 +-
 mysql-slow_extended.patch                     |  42 +-
 mysql-sql_no_fcache.patch                     |  68 +-
 mysql-suppress_log_warning_1592.patch         |  10 +-
 40 files changed, 1584 insertions(+), 990 deletions(-)
---
diff --git a/mysql-bug580324.patch b/mysql-bug580324.patch
index 3947fde..cfe6e89 100644
--- a/mysql-bug580324.patch
+++ b/mysql-bug580324.patch
@@ -26,7 +26,7 @@ diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
 diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
 --- a/sql/sql_parse.cc	2010-05-27 19:54:18.000000000 +0400
 +++ b/sql/sql_parse.cc	2010-05-27 20:03:20.000000000 +0400
-@@ -1327,10 +1327,12 @@
+@@ -1341,10 +1341,12 @@
      break;
  #else
    {
@@ -41,7 +41,7 @@ diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
  
      /* used as fields initializator */
      lex_start(thd);
-@@ -1342,26 +1344,22 @@
+@@ -1356,26 +1358,22 @@
      /*
        We have name + wildcard in packet, separated by endzero
      */
@@ -79,7 +79,7 @@ diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
  
      if (is_schema_db(table_list.db, table_list.db_length))
      {
-@@ -1370,9 +1368,6 @@
+@@ -1384,9 +1382,6 @@
          table_list.schema_table= schema_table;
      }
  
diff --git a/mysql-bugfix48929.patch b/mysql-bugfix48929.patch
index 04444a0..d40e88d 100644
--- a/mysql-bugfix48929.patch
+++ b/mysql-bugfix48929.patch
@@ -45,7 +45,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
  #define mysqld_charset &my_charset_latin1
  
  #ifdef HAVE_purify
-@@ -5100,28 +5104,49 @@
+@@ -5124,28 +5128,49 @@
  {
    my_socket sock,new_sock;
    uint error_count=0;
@@ -98,7 +98,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
  #ifdef HAVE_FCNTL
    socket_flags=fcntl(unix_sock, F_GETFL, 0);
  #endif
-@@ -5131,12 +5156,15 @@
+@@ -5155,12 +5180,15 @@
    MAYBE_BROKEN_SYSCALL;
    while (!abort_loop)
    {
@@ -119,7 +119,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
      {
        if (socket_errno != SOCKET_EINTR)
        {
-@@ -5146,7 +5174,7 @@
+@@ -5170,7 +5198,7 @@
        MAYBE_BROKEN_SYSCALL
        continue;
      }
@@ -128,7 +128,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
      if (abort_loop)
      {
        MAYBE_BROKEN_SYSCALL;
-@@ -5154,6 +5182,21 @@
+@@ -5178,6 +5206,21 @@
      }
  
      /* Is this a new connection request ? */
@@ -150,7 +150,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
  #ifdef HAVE_SYS_UN_H
      if (FD_ISSET(unix_sock,&readFDs))
      {
-@@ -5161,11 +5204,12 @@
+@@ -5185,11 +5228,12 @@
        flags= socket_flags;
      }
      else
diff --git a/mysql-control_online_alter_index.patch b/mysql-control_online_alter_index.patch
index 6f05020..861d06f 100644
--- a/mysql-control_online_alter_index.patch
+++ b/mysql-control_online_alter_index.patch
@@ -8,7 +8,7 @@
 diff -ruN a/sql/handler.h b/sql/handler.h
 --- a/sql/handler.h	2010-07-21 22:49:53.660561079 +0900
 +++ b/sql/handler.h	2010-07-21 22:50:24.106530090 +0900
-@@ -170,6 +170,19 @@
+@@ -169,6 +169,19 @@
  #define HA_ONLINE_DROP_UNIQUE_INDEX             (1L << 9) /*drop uniq. online*/
  #define HA_ONLINE_ADD_PK_INDEX                  (1L << 10)/*add prim. online*/
  #define HA_ONLINE_DROP_PK_INDEX                 (1L << 11)/*drop prim. online*/
@@ -31,7 +31,7 @@ diff -ruN a/sql/handler.h b/sql/handler.h
 diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
 --- a/sql/mysqld.cc	2010-07-21 22:49:54.011529414 +0900
 +++ b/sql/mysqld.cc	2010-07-21 22:50:24.112527179 +0900
-@@ -5874,6 +5874,7 @@
+@@ -5898,6 +5898,7 @@
    OPT_USERSTAT_RUNNING,
    OPT_THREAD_STATISTICS,
    OPT_OPTIMIZER_FIX,
@@ -39,7 +39,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
    OPT_SUPPRESS_LOG_WARNING_1592,
    OPT_QUERY_CACHE_STRIP_COMMENTS,
    OPT_USE_GLOBAL_LONG_QUERY_TIME,
-@@ -5905,6 +5906,13 @@
+@@ -5930,6 +5931,13 @@
     "from libc.so",
     &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
     0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -56,7 +56,7 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
 diff -ruN a/sql/set_var.cc b/sql/set_var.cc
 --- a/sql/set_var.cc	2010-07-21 22:49:54.019529438 +0900
 +++ b/sql/set_var.cc	2010-07-21 22:50:24.122532110 +0900
-@@ -748,6 +748,11 @@
+@@ -758,6 +758,11 @@
  sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
  			      &SV::engine_condition_pushdown);
  
@@ -83,7 +83,7 @@ diff -ruN a/sql/sql_class.h b/sql/sql_class.h
 diff -ruN a/sql/sql_partition.cc b/sql/sql_partition.cc
 --- a/sql/sql_partition.cc	2010-06-04 00:50:11.000000000 +0900
 +++ b/sql/sql_partition.cc	2010-07-21 22:50:24.140530183 +0900
-@@ -4359,7 +4359,12 @@
+@@ -4381,7 +4381,12 @@
          alter_info->no_parts= curr_part_no - new_part_no;
        }
      }
@@ -100,7 +100,7 @@ diff -ruN a/sql/sql_partition.cc b/sql/sql_partition.cc
 diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
 --- a/sql/sql_table.cc	2010-06-04 00:50:11.000000000 +0900
 +++ b/sql/sql_table.cc	2010-07-21 22:50:24.146531063 +0900
-@@ -6993,6 +6993,10 @@
+@@ -7003,6 +7003,10 @@
      uint  *idx_end_p;
  
      alter_flags= table->file->alter_table_flags(alter_info->flags);
diff --git a/mysql-fix-bug671764.patch b/mysql-fix-bug671764.patch
index 128d6eb..1a49e9b 100644
--- a/mysql-fix-bug671764.patch
+++ b/mysql-fix-bug671764.patch
@@ -5,10 +5,10 @@
 #!!! notice !!!
 # Any small change to this file in the main branch
 # should be done or reviewed by the maintainer!
-diff -Nur a/configure.in b/configure.in
+diff -ruN a/configure.in b/configure.in
 --- a/configure.in	2010-11-29 18:45:47.000000000 +0000
 +++ b/configure.in	2010-11-29 18:45:51.000000000 +0000
-@@ -2718,7 +2718,7 @@
+@@ -2727,7 +2727,7 @@
      MAN_DROP="$MAN_DROP embedded"
      grep -v 'embedded' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL
    fi
@@ -17,12 +17,12 @@ diff -Nur a/configure.in b/configure.in
    then
      MAN_DROP="$MAN_DROP innodb"
      grep -v 'inno' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL
-@@ -2797,7 +2797,7 @@
+@@ -2806,7 +2806,7 @@
  fi
-
+ 
  # "innochecksum" is not in the "innobase/" subdirectory, but should be switched
 -AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innobase" = Xyes])
 +AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innodb_plugin" = Xyes])
-
+ 
  # IMPORTANT - do not modify LIBS past this line - this hack is the only way
  # I know to add the static NSS magic if we have static NSS libraries with
diff --git a/mysql-i_s_innodb_buffer_pool_pages.patch b/mysql-i_s_innodb_buffer_pool_pages.patch
index d977f0c..01e9505 100644
--- a/mysql-i_s_innodb_buffer_pool_pages.patch
+++ b/mysql-i_s_innodb_buffer_pool_pages.patch
@@ -26,7 +26,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 15:55:25.000000000 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:04:05.000000000 +0900
-@@ -11175,6 +11175,9 @@
+@@ -11256,6 +11256,9 @@
    innobase_system_variables, /* system variables */
    NULL /* reserved */
  },
@@ -618,7 +618,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +
 +	/* plugin author (for SHOW PLUGINS) */
 +	/* const char* */
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +
 +	/* general descriptive text (for SHOW PLUGINS) */
 +	/* const char* */
@@ -667,7 +667,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +
 +	/* plugin author (for SHOW PLUGINS) */
 +	/* const char* */
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +
 +	/* general descriptive text (for SHOW PLUGINS) */
 +	/* const char* */
@@ -716,7 +716,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +
 +	/* plugin author (for SHOW PLUGINS) */
 +	/* const char* */
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +
 +	/* general descriptive text (for SHOW PLUGINS) */
 +	/* const char* */
diff --git a/mysql-innodb_adjust_defaults.patch b/mysql-innodb_adjust_defaults.patch
index 4f1b805..aaf55ef 100644
--- a/mysql-innodb_adjust_defaults.patch
+++ b/mysql-innodb_adjust_defaults.patch
@@ -8,16 +8,16 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-30 16:39:14.000000000 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-30 16:43:26.000000000 +0900
-@@ -11223,7 +11223,7 @@
+@@ -11300,7 +11300,7 @@
  static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
    PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
    "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
--  NULL, NULL, 0, 0, 64, 0);
-+  NULL, NULL, 1, 0, 64, 0);
+-  NULL, NULL, 0, 0, UNIV_MAX_PARALLELISM, 0);
++  NULL, NULL, 1, 0, UNIV_MAX_PARALLELISM, 0);
  
  static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11323,7 +11323,7 @@
+@@ -11400,7 +11400,7 @@
  static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
    PLUGIN_VAR_NOCMDARG,
    "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
@@ -26,7 +26,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
    PLUGIN_VAR_RQCMDARG,
-@@ -11568,7 +11568,7 @@
+@@ -11633,7 +11633,7 @@
  static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
    PLUGIN_VAR_RQCMDARG,
    "Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
@@ -35,7 +35,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
    PLUGIN_VAR_RQCMDARG,
-@@ -11648,8 +11648,8 @@
+@@ -11713,8 +11713,8 @@
  };
  static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
    PLUGIN_VAR_RQCMDARG,
diff --git a/mysql-innodb_admin_command_base.patch b/mysql-innodb_admin_command_base.patch
index 4a42d19..72eec5f 100644
--- a/mysql-innodb_admin_command_base.patch
+++ b/mysql-innodb_admin_command_base.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:27:30.222410116 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:27:44.073104773 +0900
-@@ -11547,6 +11547,7 @@
+@@ -11612,6 +11612,7 @@
  i_s_innodb_cmpmem_reset,
  i_s_innodb_table_stats,
  i_s_innodb_index_stats,
@@ -149,7 +149,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
 +	STRUCT_FLD(info, &i_s_info),
 +	STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +	STRUCT_FLD(descr, "XtraDB specific command acceptor"),
 +	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
 +	STRUCT_FLD(init, i_s_innodb_admin_command_init),
diff --git a/mysql-innodb_buffer_pool_shm.patch b/mysql-innodb_buffer_pool_shm.patch
index ca55d71..3e18bbf 100644
--- a/mysql-innodb_buffer_pool_shm.patch
+++ b/mysql-innodb_buffer_pool_shm.patch
@@ -681,7 +681,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  static char*	internal_innobase_data_file_path	= NULL;
  
-@@ -2457,6 +2458,7 @@
+@@ -2476,6 +2477,7 @@
  	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
  	srv_use_checksums = (ibool) innobase_use_checksums;
  	srv_fast_checksum = (ibool) innobase_fast_checksum;
@@ -689,7 +689,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  #ifdef HAVE_LARGE_PAGES
          if ((os_use_large_pages = (ibool) my_use_large_pages))
-@@ -11418,6 +11420,16 @@
+@@ -11476,6 +11478,16 @@
    "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
    NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
  
@@ -706,7 +706,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
    PLUGIN_VAR_RQCMDARG,
    "Helps in performance tuning in heavily concurrent environments.",
-@@ -11699,6 +11711,8 @@
+@@ -11764,6 +11776,8 @@
    MYSQL_SYSVAR(additional_mem_pool_size),
    MYSQL_SYSVAR(autoextend_increment),
    MYSQL_SYSVAR(buffer_pool_size),
@@ -1131,7 +1131,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
 diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
 --- a/storage/innodb_plugin/srv/srv0start.c	2010-07-14 16:33:23.851391514 +0900
 +++ b/storage/innodb_plugin/srv/srv0start.c	2010-07-14 16:40:16.180321173 +0900
-@@ -1744,6 +1744,8 @@
+@@ -1750,6 +1750,8 @@
  		Note that this is not as heavy weight as it seems. At
  		this point there will be only ONE page in the buf_LRU
  		and there must be no page in the buf_flush list. */
diff --git a/mysql-innodb_bug60788.patch b/mysql-innodb_bug60788.patch
new file mode 100644
index 0000000..2ce33e7
--- /dev/null
+++ b/mysql-innodb_bug60788.patch
@@ -0,0 +1,124 @@
+# name       : innodb_bug60788.patch
+# maintainer : Alexey
+#
+# Fix for MySQL bug #60788: InnoDB crashes with an assertion failure when 
+#                           receiving a signal on pwrite()
+#
+# Changes InnoDB IO code so that fsync(), pread() and pwrite() are restarted
+# when interrupted by a signal.
+#
+diff -ruN a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c
+--- a/storage/innodb_plugin/os/os0file.c	2011-04-18 13:21:07.000000000 +0400
++++ b/storage/innodb_plugin/os/os0file.c	2011-04-18 17:38:21.000000000 +0400
+@@ -1978,6 +1978,9 @@
+ 			failures++;
+ 
+ 			retry = TRUE;
++		} else if (ret == -1 && errno == EINTR) {
++			/* Handle signal interruptions correctly */
++			retry = TRUE;
+ 		} else {
+ 
+ 			retry = FALSE;
+@@ -2109,6 +2112,7 @@
+ 	off_t	offs;
+ #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
+ 	ssize_t	n_bytes;
++	ssize_t n_read;
+ #endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
+ 	ulint		sec;
+ 	ulint		ms;
+@@ -2149,7 +2153,18 @@
+ 	os_n_pending_reads++;
+ 	os_mutex_exit(os_file_count_mutex);
+ 
+-	n_bytes = pread(file, buf, (ssize_t)n, offs);
++	/* Handle signal interruptions correctly */
++	for (n_bytes = 0; n_bytes < (ssize_t) n; ) {
++		n_read = pread(file, buf, (ssize_t)n, offs);
++		if (n_read > 0) {
++			n_bytes += n_read;
++			offs += n_read;
++		} else if (n_read == -1 && errno == EINTR) {
++			continue;
++		} else {
++			break;
++		}
++	}
+ 
+ 	os_mutex_enter(os_file_count_mutex);
+ 	os_file_n_pending_preads--;
+@@ -2168,6 +2183,7 @@
+ 	{
+ 		off_t	ret_offset;
+ 		ssize_t	ret;
++		ssize_t n_read;
+ #ifndef UNIV_HOTBACKUP
+ 		ulint	i;
+ #endif /* !UNIV_HOTBACKUP */
+@@ -2188,7 +2204,17 @@
+ 		if (ret_offset < 0) {
+ 			ret = -1;
+ 		} else {
+-			ret = read(file, buf, (ssize_t)n);
++			/* Handle signal interruptions correctly */
++			for (ret = 0; ret < (ssize_t) n; ) {
++				n_read = read(file, buf, (ssize_t)n);
++				if (n_read > 0) {
++					ret += n_read;
++				} else if (n_read == -1 && errno == EINTR) {
++					continue;
++				} else {
++					break;
++				}
++			}
+ 		}
+ 
+ #ifndef UNIV_HOTBACKUP
+@@ -2227,6 +2253,7 @@
+ 				offset */
+ {
+ 	ssize_t	ret;
++	ssize_t n_written;
+ 	off_t	offs;
+ 
+ 	ut_a((offset & 0xFFFFFFFFUL) == offset);
+@@ -2254,7 +2281,18 @@
+ 	os_n_pending_writes++;
+ 	os_mutex_exit(os_file_count_mutex);
+ 
+-	ret = pwrite(file, buf, (ssize_t)n, offs);
++	/* Handle signal interruptions correctly */
++	for (ret = 0; ret < (ssize_t) n; ) {
++		n_written = pwrite(file, buf, (ssize_t)n, offs);
++		if (n_written > 0) {
++			ret += n_written;
++			offs += n_written;
++		} else if (n_written == -1 && errno == EINTR) {
++			continue;
++		} else {
++			break;
++		}
++	}
+ 
+ 	os_mutex_enter(os_file_count_mutex);
+ 	os_file_n_pending_pwrites--;
+@@ -2301,7 +2339,17 @@
+ 			goto func_exit;
+ 		}
+ 
+-		ret = write(file, buf, (ssize_t)n);
++		/* Handle signal interruptions correctly */
++		for (ret = 0; ret < (ssize_t) n; ) {
++			n_written = write(file, buf, (ssize_t)n);
++			if (n_written > 0) {
++				ret += n_written;
++			} else if (n_written == -1 && errno == EINTR) {
++				continue;
++			} else {
++				break;
++			}
++		}
+ 
+ # ifdef UNIV_DO_FLUSH
+ 		if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
diff --git a/mysql-innodb_deadlock_count.patch b/mysql-innodb_deadlock_count.patch
index ecb6c84..ae4d902 100644
--- a/mysql-innodb_deadlock_count.patch
+++ b/mysql-innodb_deadlock_count.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-10 15:32:14.468241191 +0400
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-10 15:32:14.926992081 +0400
-@@ -547,6 +547,8 @@
+@@ -566,6 +566,8 @@
    (char*) &export_vars.innodb_data_written,		  SHOW_LONG},
    {"dblwr_pages_written",
    (char*) &export_vars.innodb_dblwr_pages_written,	  SHOW_LONG},
@@ -31,7 +31,7 @@ diff -ruN a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/in
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2010-08-10 15:32:14.478241628 +0400
 +++ b/storage/innodb_plugin/include/srv0srv.h	2010-08-10 15:32:14.936991959 +0400
-@@ -675,6 +675,7 @@
+@@ -689,6 +689,7 @@
  	ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
  	ulint innodb_buffer_pool_read_ahead;	/*!< srv_read_ahead */
  	ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
@@ -53,7 +53,7 @@ diff -ruN a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-08-10 15:32:14.478241628 +0400
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-08-10 15:32:14.936991959 +0400
-@@ -440,7 +440,7 @@
+@@ -444,7 +444,7 @@
  static ulint	srv_n_rows_updated_old		= 0;
  static ulint	srv_n_rows_deleted_old		= 0;
  static ulint	srv_n_rows_read_old		= 0;
@@ -62,7 +62,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  UNIV_INTERN ulint		srv_n_lock_wait_count		= 0;
  UNIV_INTERN ulint		srv_n_lock_wait_current_count	= 0;
  UNIV_INTERN ib_int64_t	srv_n_lock_wait_time		= 0;
-@@ -2151,6 +2151,8 @@
+@@ -2155,6 +2155,8 @@
  		= UT_LIST_GET_LEN(buf_pool->flush_list);
  	export_vars.innodb_buffer_pool_pages_free
  		= UT_LIST_GET_LEN(buf_pool->free);
diff --git a/mysql-innodb_expand_fast_index_creation.patch b/mysql-innodb_expand_fast_index_creation.patch
new file mode 100644
index 0000000..fc89b88
--- /dev/null
+++ b/mysql-innodb_expand_fast_index_creation.patch
@@ -0,0 +1,742 @@
+# name       : innodb_expand_fast_index_creation.patch
+# maintainer : Alexey
+#
+# Expands the applicability of InnoDB fast index creation to mysqldump,
+# ALTER TABLE and OPTIMIZE TABLE.
+#
+diff -ruN a/client/client_priv.h b/client/client_priv.h
+--- a/client/client_priv.h	2011-04-11 23:22:54.000000000 +0400
++++ b/client/client_priv.h	2011-04-11 23:22:55.000000000 +0400
+@@ -97,5 +97,6 @@
+   OPT_FIRST_SLAVE,
+   OPT_ALL,
+   OPT_NO_REMOVE_EOL_CARRET,
++  OPT_INNODB_OPTIMIZE_KEYS,
+   OPT_MAX_CLIENT_OPTION
+ };
+diff -ruN a/client/mysqldump.c b/client/mysqldump.c
+--- a/client/mysqldump.c	2011-04-11 23:22:49.000000000 +0400
++++ b/client/mysqldump.c	2011-04-11 23:22:55.000000000 +0400
+@@ -45,6 +45,7 @@
+ #include <m_ctype.h>
+ #include <hash.h>
+ #include <stdarg.h>
++#include <my_list.h>
+ 
+ #include "client_priv.h"
+ #include "mysql.h"
+@@ -134,6 +135,8 @@
+ 
+ static my_bool server_supports_sql_no_fcache= FALSE;
+ 
++static my_bool opt_innodb_optimize_keys= FALSE;
++
+ /*
+ Dynamic_string wrapper functions. In this file use these
+ wrappers, they will terminate the process if there is
+@@ -179,6 +182,8 @@
+ 
+ HASH ignore_table;
+ 
++LIST *skipped_keys_list;
++
+ static struct my_option my_long_options[] =
+ {
+   {"all", OPT_ALL, "Deprecated. Use --create-options instead.",
+@@ -325,6 +330,11 @@
+    "be specified with both database and table names, e.g., "
+    "--ignore-table=database.table.",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++  {"innodb-optimize-keys", OPT_INNODB_OPTIMIZE_KEYS,
++   "Use InnoDB fast index creation by creating secondary indexes after "
++   "dumping the data.",
++   &opt_innodb_optimize_keys, &opt_innodb_optimize_keys, 0, GET_BOOL, NO_ARG,
++   0, 0, 0, 0, 0, 0},
+   {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
+    &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+    0, 0},
+@@ -2246,6 +2256,77 @@
+ }
+ 
+ /*
++  Remove secondary/foreign key definitions from a given SHOW CREATE TABLE string
++  and store them into a temporary list to be used later.
++
++  SYNOPSIS
++    skip_secondary_keys()
++    create_str                SHOW CREATE TABLE output
++
++
++  DESCRIPTION
++
++    Stores all lines starting with "KEY" or "UNIQUE KEY" or "CONSTRAINT"
++    into skipped_keys_list and removes them from the input string.
++    Ignoring FOREIGN KEYS constraints when creating the table is ok, because
++    mysqldump sets foreign_key_checks to 0 anyway.
++*/
++
++static void skip_secondary_keys(char *create_str)
++{
++  char *ptr, *strend;
++  char *last_comma = NULL;
++
++  strend= create_str + strlen(create_str);
++
++  ptr= create_str;
++  while (*ptr)
++  {
++    char *tmp, *orig_ptr;
++
++    orig_ptr= ptr;
++    /* Skip leading whitespace */
++    while (*ptr && my_isspace(charset_info, *ptr))
++      ptr++;
++
++    /* Read the next line */
++    for (tmp= ptr; *tmp != '\n' && *tmp != '\0'; tmp++);
++
++    /* Is it a secondary index definition? */
++    if (*tmp == '\n' &&
++        (!strncmp(ptr, "UNIQUE KEY ", sizeof("UNIQUE KEY ") - 1) ||
++         !strncmp(ptr, "KEY ", sizeof("KEY ") - 1) ||
++         !strncmp(ptr, "CONSTRAINT ", sizeof("CONSTRAINT ") - 1)))
++    {
++      char *data, *end= tmp - 1;
++
++      /* Remove the trailing comma */
++      if (*end == ',')
++        end--;
++      data= my_strndup(ptr, end - ptr + 1, MYF(MY_FAE));
++      skipped_keys_list= list_cons(data, skipped_keys_list);
++
++      memmove(orig_ptr, tmp + 1, strend - tmp);
++      ptr= orig_ptr;
++      strend-= tmp + 1 - ptr;
++
++      /* Remove the comma on the previos line */
++      if (last_comma != NULL)
++      {
++        *last_comma= ' ';
++        last_comma = NULL;
++      }
++    }
++    else
++    {
++      if (tmp[-1] == ',')
++        last_comma= tmp - 1;
++      ptr= (*tmp == '\0') ? tmp : tmp + 1;
++    }
++  }
++}
++
++/*
+   get_table_structure -- retrievs database structure, prints out corresponding
+   CREATE statement and fills out insert_pat if the table is the type we will
+   be dumping.
+@@ -2486,6 +2567,9 @@
+ 
+       row= mysql_fetch_row(result);
+ 
++      if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB"))
++        skip_secondary_keys(row[1]);
++
+       fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" :
+               "/*!40101 SET @saved_cs_client     = @@character_set_client */;\n"
+               "/*!40101 SET character_set_client = utf8 */;\n"
+@@ -3578,6 +3662,27 @@
+       goto err;
+     }
+ 
++    /* Perform delayed secondary index creation for --innodb-optimize-keys */
++    if (skipped_keys_list)
++    {
++      uint keys;
++      skipped_keys_list= list_reverse(skipped_keys_list);
++      fprintf(md_result_file, "ALTER TABLE %s ", opt_quoted_table);
++      for (keys= list_length(skipped_keys_list); keys > 0; keys--)
++      {
++        LIST *node= skipped_keys_list;
++        char *def= node->data;
++
++        fprintf(md_result_file, "ADD %s%s", def, (keys > 1) ? ", " : ";\n");
++
++        skipped_keys_list= list_delete(skipped_keys_list, node);
++        my_free(def, MYF(0));
++        my_free(node, MYF(0));
++      }
++
++      DBUG_ASSERT(skipped_keys_list == NULL);
++    }
++
+     /* Moved enable keys to before unlock per bug 15977 */
+     if (opt_disable_keys)
+     {
+diff -ruN /dev/null b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result	2011-04-11 23:22:55.000000000 +0400
+@@ -0,0 +1,109 @@
++#
++# Test the --innodb-optimize-keys option.
++#
++CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, KEY(b)) ENGINE=MyISAM;
++######################################
++
++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
++/*!40101 SET NAMES utf8 */;
++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
++/*!40103 SET TIME_ZONE='+00:00' */;
++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
++DROP TABLE IF EXISTS `t1`;
++/*!40101 SET @saved_cs_client     = @@character_set_client */;
++/*!40101 SET character_set_client = utf8 */;
++CREATE TABLE `t1` (
++  `a` int(11) NOT NULL,
++  `b` int(11) DEFAULT NULL,
++  PRIMARY KEY (`a`),
++  KEY `b` (`b`)
++) ENGINE=MyISAM DEFAULT CHARSET=latin1;
++/*!40101 SET character_set_client = @saved_cs_client */;
++
++LOCK TABLES `t1` WRITE;
++/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
++/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
++UNLOCK TABLES;
++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
++
++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
++
++######################################
++DROP TABLE t1;
++CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
++INSERT INTO t2 VALUES (0), (1), (2);
++CREATE TABLE t1 (
++id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
++a INT, b VARCHAR(255), c DECIMAL(10,3),
++KEY (b),
++UNIQUE KEY uniq(c,a),
++FOREIGN KEY (a) REFERENCES t2(a) ON DELETE CASCADE
++) ENGINE=InnoDB;
++INSERT INTO t1(a,b,c) VALUES (0, "0", 0.0), (1, "1", 1.1), (2, "2", 2.2);
++######################################
++
++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
++/*!40101 SET NAMES utf8 */;
++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
++/*!40103 SET TIME_ZONE='+00:00' */;
++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
++DROP TABLE IF EXISTS `t1`;
++/*!40101 SET @saved_cs_client     = @@character_set_client */;
++/*!40101 SET character_set_client = utf8 */;
++CREATE TABLE `t1` (
++  `id` int(11) NOT NULL AUTO_INCREMENT,
++  `a` int(11) DEFAULT NULL,
++  `b` varchar(255) DEFAULT NULL,
++  `c` decimal(10,3) DEFAULT NULL,
++  PRIMARY KEY (`id`) 
++) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
++/*!40101 SET character_set_client = @saved_cs_client */;
++
++LOCK TABLES `t1` WRITE;
++/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
++INSERT INTO `t1` VALUES (1,0,'0','0.000'),(2,1,'1','1.100'),(3,2,'2','2.200');
++ALTER TABLE `t1` ADD UNIQUE KEY `uniq` (`c`,`a`), ADD KEY `b` (`b`), ADD KEY `a` (`a`), ADD CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`a`) ON DELETE CASCADE;
++/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
++UNLOCK TABLES;
++DROP TABLE IF EXISTS `t2`;
++/*!40101 SET @saved_cs_client     = @@character_set_client */;
++/*!40101 SET character_set_client = utf8 */;
++CREATE TABLE `t2` (
++  `a` int(11) NOT NULL,
++  PRIMARY KEY (`a`)
++) ENGINE=InnoDB DEFAULT CHARSET=latin1;
++/*!40101 SET character_set_client = @saved_cs_client */;
++
++LOCK TABLES `t2` WRITE;
++/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
++INSERT INTO `t2` VALUES (0),(1),(2);
++/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
++UNLOCK TABLES;
++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
++
++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
++
++######################################
++DROP TABLE t1, t2;
+diff -ruN a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result
+--- a/mysql-test/suite/innodb_plugin/r/innodb.result	2011-02-11 22:49:37.000000000 +0300
++++ b/mysql-test/suite/innodb_plugin/r/innodb.result	2011-04-11 23:22:55.000000000 +0400
+@@ -1679,7 +1679,7 @@
+ 71
+ SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
+ variable_value - @innodb_rows_inserted_orig
+-1067
++1109
+ SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
+ variable_value - @innodb_rows_updated_orig
+ 866
+diff -ruN a/mysql-test/suite/innodb_plugin/t/innodb-index.test b/mysql-test/suite/innodb_plugin/t/innodb-index.test
+--- a/mysql-test/suite/innodb_plugin/t/innodb-index.test	2011-02-11 22:49:34.000000000 +0300
++++ b/mysql-test/suite/innodb_plugin/t/innodb-index.test	2011-04-11 23:22:55.000000000 +0400
+@@ -38,6 +38,11 @@
+ show create table t1;
+ --error ER_MULTIPLE_PRI_KEY
+ alter table t1 add primary key (c);
++# Suppress the error log messages occuring on duplicate key error
++# during ALTER TABLE when using fast index creation
++--disable_query_log
++call mtr.add_suppression("Cannot find index PRIMARY in InnoDB index translation table.");
++--enable_query_log
+ --error ER_DUP_ENTRY
+ alter table t1 drop primary key, add primary key (b);
+ create unique index c on t1 (c);
+diff -ruN a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test
+--- a/mysql-test/suite/innodb_plugin/t/innodb.test	2011-02-11 22:49:35.000000000 +0300
++++ b/mysql-test/suite/innodb_plugin/t/innodb.test	2011-04-11 23:22:55.000000000 +0400
+@@ -15,6 +15,12 @@
+ 
+ -- source include/have_innodb_plugin.inc
+ 
++# Suppress the error log message occuring on duplicate key error
++# during ALTER TABLE when using fast index creation
++--disable_query_log
++call mtr.add_suppression("Cannot find index v_2 in InnoDB index translation table.");
++--enable_query_log
++
+ let $MYSQLD_DATADIR= `select @@datadir`;
+ 
+ # Save the original values of some variables in order to be able to
+diff -ruN /dev/null b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test	2011-04-11 23:22:55.000000000 +0400
+@@ -0,0 +1,62 @@
++# Embedded server doesn't support external clients
++--source include/not_embedded.inc
++
++# Fast index creation is only available in InnoDB plugin
++--source include/have_innodb_plugin.inc
++
++# Save the initial number of concurrent sessions
++--source include/count_sessions.inc
++
++--echo #
++--echo # Test the --innodb-optimize-keys option.
++--echo #
++
++--let $file=$MYSQLTEST_VARDIR/tmp/t1.sql
++
++# First test that the option has no effect on non-InnoDB tables
++
++CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, KEY(b)) ENGINE=MyISAM;
++
++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 >$file
++
++--echo ######################################
++--cat_file $file
++--echo ######################################
++
++--remove_file $file
++
++DROP TABLE t1;
++
++
++# Check that for InnoDB tables secondary and foreign keys are created
++# after the data is dumped
++
++CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
++INSERT INTO t2 VALUES (0), (1), (2);
++
++CREATE TABLE t1 (
++  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
++  a INT, b VARCHAR(255), c DECIMAL(10,3),
++  KEY (b),
++  UNIQUE KEY uniq(c,a),
++  FOREIGN KEY (a) REFERENCES t2(a) ON DELETE CASCADE
++) ENGINE=InnoDB;
++
++INSERT INTO t1(a,b,c) VALUES (0, "0", 0.0), (1, "1", 1.1), (2, "2", 2.2);
++
++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 t2 >$file
++
++--echo ######################################
++--cat_file $file
++--echo ######################################
++
++# Check that the resulting dump can be imported back
++
++--exec $MYSQL test < $file
++
++--remove_file $file
++
++DROP TABLE t1, t2;
++
++# Wait till we reached the initial number of concurrent sessions
++--source include/wait_until_count_sessions.inc
+diff -ruN a/sql/sql_lex.cc b/sql/sql_lex.cc
+--- a/sql/sql_lex.cc	2011-04-11 23:22:49.000000000 +0400
++++ b/sql/sql_lex.cc	2011-04-11 23:22:55.000000000 +0400
+@@ -1494,6 +1494,9 @@
+   alter_list(rhs.alter_list, mem_root),
+   key_list(rhs.key_list, mem_root),
+   create_list(rhs.create_list, mem_root),
++  delayed_key_list(rhs.delayed_key_list, mem_root),
++  delayed_key_info(rhs.delayed_key_info),
++  delayed_key_count(rhs.delayed_key_count),
+   flags(rhs.flags),
+   keys_onoff(rhs.keys_onoff),
+   tablespace_op(rhs.tablespace_op),
+@@ -1516,6 +1519,7 @@
+   list_copy_and_replace_each_value(alter_list, mem_root);
+   list_copy_and_replace_each_value(key_list, mem_root);
+   list_copy_and_replace_each_value(create_list, mem_root);
++  list_copy_and_replace_each_value(delayed_key_list, mem_root);
+   /* partition_names are not deeply copied currently */
+ }
+ 
+diff -ruN a/sql/sql_lex.h b/sql/sql_lex.h
+--- a/sql/sql_lex.h	2011-04-11 23:22:50.000000000 +0400
++++ b/sql/sql_lex.h	2011-04-11 23:22:55.000000000 +0400
+@@ -896,6 +896,9 @@
+   List<Alter_column>            alter_list;
+   List<Key>                     key_list;
+   List<Create_field>            create_list;
++  List<Key>                     delayed_key_list;
++  KEY                           *delayed_key_info;
++  uint                          delayed_key_count;
+   uint                          flags;
+   enum enum_enable_or_disable   keys_onoff;
+   enum tablespace_op_type       tablespace_op;
+@@ -907,6 +910,8 @@
+ 
+ 
+   Alter_info() :
++    delayed_key_info(NULL),
++    delayed_key_count(0),
+     flags(0),
+     keys_onoff(LEAVE_AS_IS),
+     tablespace_op(NO_TABLESPACE_OP),
+@@ -922,6 +927,9 @@
+     alter_list.empty();
+     key_list.empty();
+     create_list.empty();
++    delayed_key_list.empty();
++    delayed_key_info= NULL;
++    delayed_key_count= 0;
+     flags= 0;
+     keys_onoff= LEAVE_AS_IS;
+     tablespace_op= NO_TABLESPACE_OP;
+diff -ruN a/sql/sql_table.cc b/sql/sql_table.cc
+--- a/sql/sql_table.cc	2011-04-11 23:22:40.000000000 +0400
++++ b/sql/sql_table.cc	2011-04-11 23:44:23.000000000 +0400
+@@ -2559,7 +2559,7 @@
+       file                      The handler for the new table.
+       key_info_buffer     OUT   An array of KEY structs for the indexes.
+       key_count           OUT   The number of elements in the array.
+-      select_field_count        The number of fields coming from a select table.
++      select_field_count        The number of fields coming from a select table. 
+ 
+   DESCRIPTION
+     Prepares the table and key structures for table creation.
+@@ -2914,7 +2914,6 @@
+   }
+ 
+   /* Create keys */
+-
+   List_iterator<Key> key_iterator(alter_info->key_list);
+   List_iterator<Key> key_iterator2(alter_info->key_list);
+   uint key_parts=0, fk_key_count=0;
+@@ -3014,6 +3013,14 @@
+   if (!*key_info_buffer || ! key_part_info)
+     DBUG_RETURN(TRUE);				// Out of memory
+ 
++  List_iterator<Key> delayed_key_iterator(alter_info->delayed_key_list);
++  alter_info->delayed_key_count= 0;
++  if (alter_info->delayed_key_list.elements > 0)
++  {
++    alter_info->delayed_key_info= (KEY *) sql_calloc(sizeof(KEY) *
++                                                     (*key_count));
++  }
++
+   key_iterator.rewind();
+   key_number=0;
+   for (; (key=key_iterator++) ; key_number++)
+@@ -3392,8 +3399,26 @@
+       my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
+       DBUG_RETURN(TRUE);
+     }
++
++    if (alter_info->delayed_key_list.elements > 0)
++    {
++      Key *delayed_key;
++
++      delayed_key_iterator.rewind();
++      while ((delayed_key= delayed_key_iterator++))
++      {
++        if (delayed_key == key)
++        {
++         alter_info->delayed_key_info[alter_info->delayed_key_count++]=
++           *key_info;
++         break;
++        }
++      }
++    }
++
+     key_info++;
+   }
++
+   if (!unique_key && !primary_key &&
+       (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
+   {
+@@ -6091,6 +6116,10 @@
+   List<Create_field> new_create_list;
+   /* New key definitions are added here */
+   List<Key> new_key_list;
++  /* List with secondary keys which should be created after copying the data */
++  List<Key> delayed_key_list;
++  /* Foreign key list returned by handler::get_foreign_key_list() */
++  List<FOREIGN_KEY_INFO> f_key_list;
+   List_iterator<Alter_drop> drop_it(alter_info->drop_list);
+   List_iterator<Create_field> def_it(alter_info->create_list);
+   List_iterator<Alter_column> alter_it(alter_info->alter_list);
+@@ -6103,6 +6132,7 @@
+   uint used_fields= create_info->used_fields;
+   KEY *key_info=table->key_info;
+   bool rc= TRUE;
++  bool skip_secondary;
+ 
+   DBUG_ENTER("mysql_prepare_alter_table");
+ 
+@@ -6130,6 +6160,7 @@
+     char *tablespace= static_cast<char *>(thd->alloc(FN_LEN + 1));
+     /*
+        Regular alter table of disk stored table (no tablespace/storage change)
++
+        Copy tablespace name
+     */
+     if (tablespace &&
+@@ -6280,7 +6311,23 @@
+   /*
+     Collect all keys which isn't in drop list. Add only those
+     for which some fields exists.
+-  */
++
++    We also store secondary keys in delayed_key_list to make use of
++    the InnoDB fast index creation. The following conditions must be
++    met:
++
++    - we are going to create an InnoDB table (this is checked later when the
++      target engine is known);
++    - the key most be a non-UNIQUE one;
++    - there are no foreign keys. This can be optimized later to exclude only
++      those keys which are a part of foreign key constraints. Currently we
++      simply disable this optimization for all keys if there are any foreign
++      key constraints in the table.
++  */
++
++  skip_secondary=
++    !table->file->get_foreign_key_list(thd, &f_key_list) &&
++    f_key_list.elements == 0;
+ 
+   for (uint i=0 ; i < table->s->keys ; i++,key_info++)
+   {
+@@ -6383,6 +6430,8 @@
+                    test(key_info->flags & HA_GENERATED_KEY),
+                    key_parts);
+       new_key_list.push_back(key);
++      if (skip_secondary && key_type == Key::MULTIPLE)
++        delayed_key_list.push_back(key);
+     }
+   }
+   {
+@@ -6390,7 +6439,21 @@
+     while ((key=key_it++))			// Add new keys
+     {
+       if (key->type != Key::FOREIGN_KEY)
+-        new_key_list.push_back(key);
++      {
++          new_key_list.push_back(key);
++        if (skip_secondary && key->type == Key::MULTIPLE)
++          delayed_key_list.push_back(key);
++      }
++      else if (skip_secondary)
++      {
++        /*
++          We are adding a foreign key so disable the secondary keys
++          optimization.
++        */
++        skip_secondary= FALSE;
++        delayed_key_list.empty();
++      }
++
+       if (key->name &&
+ 	  !my_strcasecmp(system_charset_info,key->name,primary_key_name))
+       {
+@@ -6439,12 +6502,100 @@
+   rc= FALSE;
+   alter_info->create_list.swap(new_create_list);
+   alter_info->key_list.swap(new_key_list);
++  alter_info->delayed_key_list.swap(delayed_key_list);
+ err:
+   DBUG_RETURN(rc);
+ }
+ 
+ 
+ /*
++  Temporarily remove secondary keys previously stored in
++  alter_info->delayed_key_info.
++*/
++static int
++remove_secondary_keys(THD *thd, TABLE *table, Alter_info *alter_info)
++{
++  uint *key_numbers;
++  uint key_counter= 0;
++  uint i;
++  int error;
++  DBUG_ENTER("remove_secondary_keys");
++  DBUG_ASSERT(alter_info->delayed_key_count > 0);
++
++  key_numbers= (uint *) thd->alloc(sizeof(uint) *
++                                   alter_info->delayed_key_count);
++  for (i= 0; i < alter_info->delayed_key_count; i++)
++  {
++    KEY *key= alter_info->delayed_key_info + i;
++    uint j;
++
++    for (j= 0; j < table->s->keys; j++)
++    {
++      if (!strcmp(table->key_info[j].name, key->name))
++      {
++        key_numbers[key_counter++]= j;
++        break;
++      }
++    }
++  }
++
++  DBUG_ASSERT(key_counter == alter_info->delayed_key_count);
++
++  if ((error= table->file->prepare_drop_index(table, key_numbers,
++                                              key_counter)) ||
++      (error= table->file->final_drop_index(table)))
++  {
++    table->file->print_error(error, MYF(0));
++  }
++
++  DBUG_RETURN(error);
++}
++
++/*
++  Restore secondary keys previously removed in remove_secondary_keys.
++*/
++
++static int
++restore_secondary_keys(THD *thd, TABLE *table, Alter_info *alter_info)
++{
++  uint i;
++  int error;
++  DBUG_ENTER("restore_secondary_keys");
++  DBUG_ASSERT(alter_info->delayed_key_count > 0);
++
++  thd_proc_info(thd, "restoring secondary keys");
++
++  /* Fix the key parts */
++  for (i= 0; i < alter_info->delayed_key_count; i++)
++  {
++    KEY *key = alter_info->delayed_key_info + i;
++    KEY_PART_INFO *key_part;
++    KEY_PART_INFO *part_end;
++
++    part_end= key->key_part + key->key_parts;
++    for (key_part= key->key_part; key_part < part_end; key_part++)
++      key_part->field= table->field[key_part->fieldnr];
++  }
++
++  if ((error= table->file->add_index(table, alter_info->delayed_key_info,
++                                     alter_info->delayed_key_count)))
++  {
++    /*
++      Exchange the key_info for the error message. If we exchange
++      key number by key name in the message later, we need correct info.
++    */
++    KEY *save_key_info= table->key_info;
++    table->key_info= alter_info->delayed_key_info;
++    table->file->print_error(error, MYF(0));
++    table->key_info= save_key_info;
++
++    DBUG_RETURN(error);
++  }
++
++  DBUG_RETURN(0);
++}
++
++/*
+   Alter table
+ 
+   SYNOPSIS
+@@ -7228,6 +7379,12 @@
+   else
+     create_info->data_file_name=create_info->index_file_name=0;
+ 
++  /*
++    Postpone secondary index creation for InnoDB tables if the data has to be
++    copied.
++    TODO: is there a better way to check for InnoDB?
++  */
++
+   DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
+   /*
+     Create a table with a temporary name.
+@@ -7284,15 +7441,33 @@
+   */
+   if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
+   {
++    /*
++      Check if we can temporarily remove secondary indexes from the table
++      before copying the data and recreate them later to utilize InnoDB fast
++      index creation.
++      TODO: is there a better way to check for InnoDB?
++    */
++    bool optimize_keys= (alter_info->delayed_key_count > 0) &&
++      !my_strcasecmp(system_charset_info,
++                     new_table->file->table_type(), "InnoDB");
+     /* We don't want update TIMESTAMP fields during ALTER TABLE. */
+     new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+     new_table->next_number_field=new_table->found_next_number_field;
++
++    if (optimize_keys)
++    {
++      /* ignore the error */
++      error= remove_secondary_keys(thd, new_table, alter_info);
++    }
++
+     thd_proc_info(thd, "copy to tmp table");
+     error= copy_data_between_tables(table, new_table,
+                                     alter_info->create_list, ignore,
+                                     order_num, order, &copied, &deleted,
+                                     alter_info->keys_onoff,
+                                     alter_info->error_if_not_empty);
++    if (!error && optimize_keys)
++      error= restore_secondary_keys(thd, new_table, alter_info);
+   }
+   else
+   {
diff --git a/mysql-innodb_expand_import.patch b/mysql-innodb_expand_import.patch
index bec7eef..8238cf8 100644
--- a/mysql-innodb_expand_import.patch
+++ b/mysql-innodb_expand_import.patch
@@ -104,7 +104,7 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
 +
 +		if (size_bytes < free_limit_bytes) {
 +			free_limit_bytes = size_bytes;
-+			if (size_bytes >= FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) {
++			if (size_bytes >= (ib_int64_t) (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE)) {
 +				fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
 +				file_is_corrupt = TRUE;
 +			}
@@ -500,7 +500,7 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:54:08.000000000 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-30 10:28:05.000000000 +0900
-@@ -7106,6 +7106,14 @@
+@@ -7125,6 +7125,14 @@
  		err = row_discard_tablespace_for_mysql(dict_table->name, trx);
  	} else {
  		err = row_import_tablespace_for_mysql(dict_table->name, trx);
@@ -515,7 +515,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	}
  
  	err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
-@@ -11307,6 +11315,11 @@
+@@ -11387,6 +11395,11 @@
    "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
    NULL, NULL, 0, 0, 1, 0);
  
@@ -527,7 +527,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments,
    PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
    "Number of extra user rollback segments when create new database.",
-@@ -11383,6 +11396,7 @@
+@@ -11464,6 +11477,7 @@
    MYSQL_SYSVAR(adaptive_checkpoint),
    MYSQL_SYSVAR(flush_log_at_trx_commit_session),
    MYSQL_SYSVAR(enable_unsafe_group_commit),
@@ -549,7 +549,7 @@ diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_p
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2010-04-29 16:54:08.000000000 +0900
 +++ b/storage/innodb_plugin/include/srv0srv.h	2010-04-30 10:28:05.000000000 +0900
-@@ -213,6 +213,8 @@
+@@ -218,6 +218,8 @@
  extern ulint	srv_read_ahead;
  extern ulint	srv_adaptive_checkpoint;
  
@@ -561,7 +561,7 @@ diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-04-29 18:58:20.000000000 +0900
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-04-30 10:28:05.000000000 +0900
-@@ -385,6 +385,8 @@
+@@ -390,6 +390,8 @@
  UNIV_INTERN ulint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
  UNIV_INTERN ulint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
  
diff --git a/mysql-innodb_expand_undo_slots.patch b/mysql-innodb_expand_undo_slots.patch
index 7af0902..57b2bcb 100644
--- a/mysql-innodb_expand_undo_slots.patch
+++ b/mysql-innodb_expand_undo_slots.patch
@@ -16,7 +16,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static my_bool	innobase_locks_unsafe_for_binlog	= FALSE;
  static my_bool	innobase_rollback_on_timeout		= FALSE;
  static my_bool	innobase_create_status_file		= FALSE;
-@@ -2103,6 +2104,8 @@
+@@ -2122,6 +2123,8 @@
  		goto error;
  	}
  
@@ -25,7 +25,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* -------------- Log files ---------------------------*/
  
  	/* The default dir for log files is the datadir of MySQL */
-@@ -10712,6 +10715,13 @@
+@@ -10785,6 +10788,13 @@
    "The common part for InnoDB table spaces.",
    NULL, NULL, NULL);
  
@@ -39,7 +39,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
    "Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11097,6 +11107,7 @@
+@@ -11177,6 +11187,7 @@
    MYSQL_SYSVAR(data_file_path),
    MYSQL_SYSVAR(data_home_dir),
    MYSQL_SYSVAR(doublewrite),
diff --git a/mysql-innodb_fast_checksum.patch b/mysql-innodb_fast_checksum.patch
index b13a729..51dbfa6 100644
--- a/mysql-innodb_fast_checksum.patch
+++ b/mysql-innodb_fast_checksum.patch
@@ -170,7 +170,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static my_bool	innobase_extra_undoslots		= FALSE;
  static my_bool	innobase_fast_recovery			= FALSE;
  static my_bool	innobase_recovery_stats			= TRUE;
-@@ -2394,6 +2395,7 @@
+@@ -2413,6 +2414,7 @@
  
  	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
  	srv_use_checksums = (ibool) innobase_use_checksums;
@@ -178,7 +178,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  #ifdef HAVE_LARGE_PAGES
          if ((os_use_large_pages = (ibool) my_use_large_pages))
-@@ -11118,6 +11120,15 @@
+@@ -11195,6 +11197,15 @@
    "Disable with --skip-innodb-checksums.",
    NULL, NULL, TRUE);
  
@@ -194,7 +194,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
    PLUGIN_VAR_READONLY,
    "The common part for InnoDB table spaces.",
-@@ -11610,6 +11621,7 @@
+@@ -11675,6 +11686,7 @@
    MYSQL_SYSVAR(autoextend_increment),
    MYSQL_SYSVAR(buffer_pool_size),
    MYSQL_SYSVAR(checksums),
@@ -241,7 +241,7 @@ diff -ruN a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2010-08-27 16:40:36.580092150 +0900
 +++ b/storage/innodb_plugin/include/srv0srv.h	2010-08-27 16:42:03.640988120 +0900
-@@ -211,6 +211,7 @@
+@@ -212,6 +212,7 @@
  
  extern ibool	srv_use_doublewrite_buf;
  extern ibool	srv_use_checksums;
@@ -301,7 +301,7 @@ diff -ruN a/storage/innodb_plugin/include/ut0rnd.ic b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-08-27 16:40:36.599058304 +0900
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-08-27 16:42:03.647012289 +0900
-@@ -383,6 +383,7 @@
+@@ -387,6 +387,7 @@
  
  UNIV_INTERN ibool	srv_use_doublewrite_buf	= TRUE;
  UNIV_INTERN ibool	srv_use_checksums = TRUE;
diff --git a/mysql-innodb_fast_shutdown.patch b/mysql-innodb_fast_shutdown.patch
index 22ba723..b53063a 100644
--- a/mysql-innodb_fast_shutdown.patch
+++ b/mysql-innodb_fast_shutdown.patch
@@ -165,7 +165,7 @@ diff -ruN a/storage/innodb_plugin/os/os0sync.c b/storage/innodb_plugin/os/os0syn
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-11-16 21:33:00.000000000 +0300
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-11-16 21:34:06.000000000 +0300
-@@ -709,6 +709,8 @@
+@@ -713,6 +713,8 @@
  
  UNIV_INTERN os_event_t	srv_lock_timeout_thread_event;
  
@@ -174,7 +174,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  UNIV_INTERN srv_sys_t*	srv_sys	= NULL;
  
  /* padding to prevent other memory update hotspots from residing on
-@@ -1014,6 +1016,7 @@
+@@ -1018,6 +1020,7 @@
  	}
  
  	srv_lock_timeout_thread_event = os_event_create(NULL);
@@ -182,7 +182,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	for (i = 0; i < SRV_MASTER + 1; i++) {
  		srv_n_threads_active[i] = 0;
-@@ -2241,7 +2244,7 @@
+@@ -2245,7 +2248,7 @@
  	/* Wake up every 5 seconds to see if we need to print
  	monitor information. */
  
@@ -191,7 +191,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	current_time = time(NULL);
  
-@@ -2383,7 +2386,7 @@
+@@ -2387,7 +2390,7 @@
  	/* When someone is waiting for a lock, we wake up every second
  	and check if a timeout has passed for a lock wait */
  
@@ -200,7 +200,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	srv_lock_timeout_active = TRUE;
  
-@@ -2548,7 +2551,7 @@
+@@ -2561,7 +2564,7 @@
  
  	fflush(stderr);
  
@@ -209,7 +209,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
  
-@@ -2592,7 +2595,7 @@
+@@ -2605,7 +2608,7 @@
  	last_dump_time = time(NULL);
  
  loop:
@@ -218,7 +218,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
  		goto exit_func;
-@@ -2775,7 +2778,7 @@
+@@ -2788,7 +2791,7 @@
  		if (!skip_sleep) {
  		if (next_itr_time > cur_time) {
  
@@ -227,7 +227,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  			srv_main_sleeps++;
  
  			/*
-@@ -3482,9 +3485,10 @@
+@@ -3495,9 +3498,10 @@
  		mutex_exit(&kernel_mutex);
  
  		sleep_ms = 10;
diff --git a/mysql-innodb_files_extend.patch b/mysql-innodb_files_extend.patch
index 2121ffb..e4d6fa8 100644
--- a/mysql-innodb_files_extend.patch
+++ b/mysql-innodb_files_extend.patch
@@ -124,7 +124,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static my_bool innobase_thread_concurrency_timer_based;
  static long long innobase_buffer_pool_size, innobase_log_file_size;
  
-@@ -2084,6 +2087,62 @@
+@@ -2103,6 +2106,62 @@
  	}
  #endif /* UNIV_DEBUG */
  
@@ -187,7 +187,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  #ifndef MYSQL_SERVER
  	innodb_overwrite_relay_log_info = FALSE;
  #endif
-@@ -7015,9 +7074,9 @@
+@@ -7034,9 +7093,9 @@
  				| DICT_TF_COMPACT
  				| DICT_TF_FORMAT_ZIP
  				<< DICT_TF_FORMAT_SHIFT;
@@ -200,7 +200,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		}
  	}
  
-@@ -11129,6 +11188,16 @@
+@@ -11206,6 +11265,16 @@
    "#### Attention: The checksum is not compatible for normal or disabled version! ####",
    NULL, NULL, FALSE);
  
@@ -217,7 +217,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
    PLUGIN_VAR_READONLY,
    "The common part for InnoDB table spaces.",
-@@ -11617,6 +11686,8 @@
+@@ -11682,6 +11751,8 @@
    NULL, NULL, 0, 0, 1, 0);
  
  static struct st_mysql_sys_var* innobase_system_variables[]= {
@@ -386,7 +386,7 @@ diff -ruN a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
 --- a/storage/innodb_plugin/include/univ.i	2010-08-04 02:24:19.000000000 +0900
 +++ b/storage/innodb_plugin/include/univ.i	2010-08-27 16:44:21.698059254 +0900
-@@ -283,9 +283,13 @@
+@@ -286,9 +286,13 @@
  */
  
  /* The 2-logarithm of UNIV_PAGE_SIZE: */
@@ -402,7 +402,7 @@ diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include
  
  /* Maximum number of parallel threads in a parallelized operation */
  #define UNIV_MAX_PARALLELISM	32
-@@ -399,7 +403,7 @@
+@@ -402,7 +406,7 @@
  stored part of the field in the tablespace. The length field then
  contains the sum of the following flag and the locally stored len. */
  
@@ -411,7 +411,7 @@ diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include
  
  /* Some macros to improve branch prediction and reduce cache misses */
  #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-@@ -502,4 +506,6 @@
+@@ -505,4 +509,6 @@
  	UNIV_MEM_ALLOC(addr, size);			\
  } while (0)
  
@@ -570,7 +570,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
 diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
 --- a/storage/innodb_plugin/srv/srv0start.c	2010-08-27 16:40:36.602058774 +0900
 +++ b/storage/innodb_plugin/srv/srv0start.c	2010-08-27 16:44:21.720021228 +0900
-@@ -1506,10 +1506,12 @@
+@@ -1512,10 +1512,12 @@
  	}
  #endif /* UNIV_LOG_ARCHIVE */
  
@@ -585,7 +585,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  
  		return(DB_ERROR);
  	}
-@@ -1518,7 +1520,7 @@
+@@ -1524,7 +1526,7 @@
  
  	for (i = 0; i < srv_n_data_files; i++) {
  #ifndef __WIN__
diff --git a/mysql-innodb_fix_misc.patch b/mysql-innodb_fix_misc.patch
index 4b6e43d..882b110 100644
--- a/mysql-innodb_fix_misc.patch
+++ b/mysql-innodb_fix_misc.patch
@@ -13,7 +13,7 @@
 diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
 --- a/storage/innodb_plugin/buf/buf0buf.c	2011-02-21 20:31:57.781983359 +0900
 +++ b/storage/innodb_plugin/buf/buf0buf.c	2011-02-21 20:32:39.523946003 +0900
-@@ -3224,6 +3224,7 @@
+@@ -3243,6 +3243,7 @@
  		bpage->state	= BUF_BLOCK_ZIP_PAGE;
  		bpage->space	= space;
  		bpage->offset	= offset;
@@ -50,7 +50,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0
 diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
 --- a/storage/innodb_plugin/buf/buf0lru.c	2011-02-21 20:31:57.451983310 +0900
 +++ b/storage/innodb_plugin/buf/buf0lru.c	2011-02-21 20:32:39.526949096 +0900
-@@ -530,6 +530,30 @@
+@@ -550,6 +550,30 @@
  	}
  }
  
@@ -81,7 +81,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0
  /********************************************************************//**
  Insert a compressed block into buf_pool->zip_clean in the LRU order. */
  UNIV_INTERN
-@@ -1498,6 +1522,10 @@
+@@ -1492,6 +1516,10 @@
  		return(BUF_LRU_NOT_FREED);
  	}
  
@@ -108,16 +108,25 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
  	ut_ad(mutex_own(&(system->mutex)));
  	ut_a(node->open);
 -	ut_a(node->n_pending == 0);
-+	ut_a(node->n_pending == 0 || srv_lazy_drop_table);
++	ut_a(node->n_pending == 0 || node->space->is_being_deleted);
  	ut_a(node->n_pending_flushes == 0);
  	ut_a(node->modification_counter == node->flush_counter);
  
+@@ -829,7 +830,7 @@
+ 	ut_a(system->n_open > 0);
+ 	system->n_open--;
+ 
+-	if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
++	if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
+ 		ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
+ 
+ 		/* The node is in the LRU list, remove it */
 @@ -1028,7 +1029,7 @@
  	ut_ad(node && system && space);
  	ut_ad(mutex_own(&(system->mutex)));
  	ut_a(node->magic_n == FIL_NODE_MAGIC_N);
 -	ut_a(node->n_pending == 0);
-+	ut_a(node->n_pending == 0 || srv_lazy_drop_table);
++	ut_a(node->n_pending == 0 || space->is_being_deleted);
  
  	if (node->open) {
  		/* We fool the assertion in fil_node_close_file() to think
@@ -282,7 +291,7 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:50:59.626327847 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:55:20.281021252 +0900
-@@ -11685,6 +11685,12 @@
+@@ -11750,6 +11750,12 @@
    "except for the deletion.",
    NULL, NULL, 0, 0, 1, 0);
  
@@ -295,7 +304,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static struct st_mysql_sys_var* innobase_system_variables[]= {
    MYSQL_SYSVAR(page_size),
    MYSQL_SYSVAR(log_block_size),
-@@ -11774,6 +11780,7 @@
+@@ -11839,6 +11845,7 @@
    MYSQL_SYSVAR(auto_lru_dump),
    MYSQL_SYSVAR(use_purge_thread),
    MYSQL_SYSVAR(pass_corrupt_table),
@@ -303,7 +312,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
    NULL
  };
  
-@@ -11783,7 +11790,7 @@
+@@ -11848,7 +11855,7 @@
    &innobase_storage_engine,
    innobase_hton_name,
    "Innobase Oy",
@@ -321,7 +330,7 @@ diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/incl
  	/* @} */
 +	ibool		space_was_being_deleted;
  	ibool		is_corrupt;
- # ifdef UNIV_DEBUG_FILE_ACCESSES
+ # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
  	ibool		file_page_was_freed;
 diff -ruN a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
 --- a/storage/innodb_plugin/include/buf0buf.ic	2011-02-21 20:31:57.725983812 +0900
@@ -385,7 +394,7 @@ diff -ruN a/storage/innodb_plugin/include/os0file.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2011-02-21 20:31:57.824983518 +0900
 +++ b/storage/innodb_plugin/include/srv0srv.h	2011-02-21 20:32:39.541913033 +0900
-@@ -235,6 +235,8 @@
+@@ -236,6 +236,8 @@
  
  extern ulint	srv_extra_rsegments;
  extern ulint	srv_dict_size_limit;
@@ -410,7 +419,7 @@ diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include
 +++ b/storage/innodb_plugin/include/univ.i	2010-04-30 16:41:46.000000000 +0900
 @@ -48,6 +48,11 @@
  #define INNODB_VERSION_MINOR	0
- #define INNODB_VERSION_BUGFIX	15
+ #define INNODB_VERSION_BUGFIX	16
  
 +#ifndef PERCONA_INNODB_VERSION
 +#define PERCONA_INNODB_VERSION 12.5
@@ -439,18 +448,6 @@ diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include
  
  #define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
  
-diff -ruN a/storage/innodb_plugin/mtr/mtr0log.c b/storage/innodb_plugin/mtr/mtr0log.c
---- a/storage/innodb_plugin/mtr/mtr0log.c	2010-11-29 19:38:03.000000000 +0900
-+++ b/storage/innodb_plugin/mtr/mtr0log.c	2011-02-02 23:31:34.000000000 +0900
-@@ -408,7 +408,7 @@
- 	ptr += 2;
- 
- 	if (UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
--			|| UNIV_UNLIKELY(len + offset) > UNIV_PAGE_SIZE) {
-+			|| UNIV_UNLIKELY(len + offset > UNIV_PAGE_SIZE)) {
- 		recv_sys->found_corrupt_log = TRUE;
- 
- 		return(NULL);
 diff -ruN a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c
 --- a/storage/innodb_plugin/os/os0file.c	2011-02-21 20:31:57.437945953 +0900
 +++ b/storage/innodb_plugin/os/os0file.c	2011-02-21 20:32:39.546945763 +0900
@@ -603,7 +600,7 @@ diff -ruN a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2011-02-21 20:31:57.900982316 +0900
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2011-02-21 20:32:39.549912950 +0900
-@@ -414,6 +414,8 @@
+@@ -418,6 +418,8 @@
  
  UNIV_INTERN ulint	srv_extra_rsegments = 0; /* extra rseg for users */
  UNIV_INTERN ulint	srv_dict_size_limit = 0;
@@ -615,7 +612,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
 diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
 --- a/storage/innodb_plugin/srv/srv0start.c	2010-04-30 16:37:05.000000000 +0900
 +++ b/storage/innodb_plugin/srv/srv0start.c	2010-04-30 16:41:46.000000000 +0900
-@@ -2006,7 +2006,7 @@
+@@ -2012,7 +2012,7 @@
  	if (srv_print_verbose_log) {
  		ut_print_timestamp(stderr);
  		fprintf(stderr,
diff --git a/mysql-innodb_lru_dump_restore.patch b/mysql-innodb_lru_dump_restore.patch
index 67cef95..faf5ddf 100644
--- a/mysql-innodb_lru_dump_restore.patch
+++ b/mysql-innodb_lru_dump_restore.patch
@@ -42,7 +42,7 @@
 diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
 --- a/storage/innodb_plugin/buf/buf0lru.c	2010-08-27 16:13:11.070058073 +0900
 +++ b/storage/innodb_plugin/buf/buf0lru.c	2010-08-27 16:34:33.860400549 +0900
-@@ -2130,6 +2130,277 @@
+@@ -2121,6 +2121,277 @@
  	memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
  }
  
@@ -409,7 +409,7 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-10-01 09:57:56.486228425 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-10-01 10:00:13.292228546 +0900
-@@ -11486,6 +11486,12 @@
+@@ -11551,6 +11551,12 @@
    "Limit the allocated memory for dictionary cache. (0: unlimited)",
    NULL, NULL, 0, 0, LONG_MAX, 0);
  
@@ -422,7 +422,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static struct st_mysql_sys_var* innobase_system_variables[]= {
    MYSQL_SYSVAR(additional_mem_pool_size),
    MYSQL_SYSVAR(autoextend_increment),
-@@ -11568,6 +11574,7 @@
+@@ -11633,6 +11639,7 @@
  #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
    MYSQL_SYSVAR(read_ahead_threshold),
    MYSQL_SYSVAR(io_capacity),
@@ -491,7 +491,7 @@ diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_p
 diff -ruN a/storage/innodb_plugin/include/buf0lru.h b/storage/innodb_plugin/include/buf0lru.h
 --- a/storage/innodb_plugin/include/buf0lru.h	2010-08-27 16:13:11.085978393 +0900
 +++ b/storage/innodb_plugin/include/buf0lru.h	2010-08-27 16:34:33.875100517 +0900
-@@ -213,6 +213,18 @@
+@@ -209,6 +209,18 @@
  void
  buf_LRU_stat_update(void);
  /*=====================*/
@@ -572,7 +572,7 @@ diff -ruN a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2010-10-01 09:57:56.500228711 +0900
 +++ b/storage/innodb_plugin/include/srv0srv.h	2010-10-01 10:00:13.302223409 +0900
-@@ -334,6 +334,9 @@
+@@ -335,6 +335,9 @@
  reading of a disk page */
  extern ulint srv_buf_pool_reads;
  
@@ -582,7 +582,7 @@ diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/incl
  /** Status variables to be passed to MySQL */
  typedef struct export_var_struct export_struc;
  
-@@ -602,6 +605,16 @@
+@@ -616,6 +619,16 @@
  /*=====================*/
  	void*	arg);	/*!< in: a dummy parameter required by
  			os_thread_create */
@@ -602,7 +602,7 @@ diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/incl
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-10-01 09:57:56.516255101 +0900
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-10-01 10:00:13.304230973 +0900
-@@ -298,6 +298,9 @@
+@@ -303,6 +303,9 @@
  reading of a disk page */
  UNIV_INTERN ulint srv_buf_pool_reads = 0;
  
@@ -612,7 +612,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  /* structure to pass status variables to MySQL */
  UNIV_INTERN export_struc export_vars;
  
-@@ -2537,6 +2540,56 @@
+@@ -2550,6 +2553,56 @@
  	/* 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. */
  
@@ -676,15 +676,15 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  static ulint		ios;
  
  /** io_handler_thread parameters for thread identification */
--static ulint		n[SRV_MAX_N_IO_THREADS + 6 + 64];
-+static ulint		n[SRV_MAX_N_IO_THREADS + 7 + 64];
+-static ulint		n[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
++static ulint		n[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
  /** io_handler_thread identifiers */
--static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64];
-+static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 7 + 64];
+-static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
++static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
  
  /** We use this mutex to test the return value of pthread_mutex_trylock
     on successful locking. HP-UX does NOT return 0, though Linux et al do. */
-@@ -1700,6 +1700,10 @@
+@@ -1706,6 +1706,10 @@
  	os_thread_create(&srv_monitor_thread, NULL,
  			 thread_ids + 4 + SRV_MAX_N_IO_THREADS);
  
@@ -695,7 +695,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  	srv_is_being_started = FALSE;
  
  	if (trx_doublewrite == NULL) {
-@@ -1724,13 +1728,13 @@
+@@ -1730,13 +1734,13 @@
  		ulint i;
  
  		os_thread_create(&srv_purge_thread, NULL, thread_ids
diff --git a/mysql-innodb_opt_lru_count.patch b/mysql-innodb_opt_lru_count.patch
index 45ef1d2..28ab45f 100644
--- a/mysql-innodb_opt_lru_count.patch
+++ b/mysql-innodb_opt_lru_count.patch
@@ -40,7 +40,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  	ut_d(bpage->in_page_hash = FALSE);
  
  	/* relocate buf_pool->LRU */
-@@ -2947,8 +2947,8 @@
+@@ -2966,8 +2966,8 @@
  		bpage->in_zip_hash = FALSE;
  		bpage->in_flush_list = FALSE;
  		bpage->in_free_list = FALSE;
@@ -50,7 +50,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  
  		ut_d(bpage->in_page_hash = TRUE);
  		HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
-@@ -3094,7 +3094,7 @@
+@@ -3113,7 +3113,7 @@
  	ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE);
  
  	/* Flush pages from the end of the LRU list if necessary */
@@ -59,7 +59,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  
  	frame = block->frame;
  
-@@ -3848,7 +3848,7 @@
+@@ -3867,7 +3867,7 @@
  {
  	ulint	ratio;
  
@@ -68,7 +68,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  
  	ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
  		/ (1 + UT_LIST_GET_LEN(buf_pool->LRU)
-@@ -3856,7 +3856,7 @@
+@@ -3875,7 +3875,7 @@
  
  	/* 1 + is there to avoid division by zero */
  
@@ -186,7 +186,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0
 diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
 --- a/storage/innodb_plugin/buf/buf0lru.c	2010-04-06 23:07:12.000000000 +0900
 +++ b/storage/innodb_plugin/buf/buf0lru.c	2010-04-29 15:55:42.000000000 +0900
-@@ -952,7 +952,7 @@
+@@ -936,7 +936,7 @@
  
  	/* No free block was found: try to flush the LRU list */
  
@@ -195,7 +195,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0
  	++srv_buf_pool_wait_free;
  
  	os_aio_simulated_wake_handler_threads();
-@@ -1143,7 +1143,7 @@
+@@ -1127,7 +1127,7 @@
  
  	/* Remove the block from the LRU list */
  	UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
@@ -204,7 +204,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0
  
  	buf_unzip_LRU_remove_block_if_needed(bpage);
  
-@@ -1218,7 +1218,7 @@
+@@ -1202,7 +1202,7 @@
  
  	ut_ad(!bpage->in_LRU_list);
  	UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
@@ -213,7 +213,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0
  
  	if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
  
-@@ -1286,7 +1286,7 @@
+@@ -1270,7 +1270,7 @@
  		buf_pool->LRU_old_len++;
  	}
  
@@ -222,7 +222,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0
  
  	if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
  
-@@ -1533,7 +1533,7 @@
+@@ -1513,7 +1513,7 @@
  				buf_page_set_old(b, buf_page_is_old(b));
  #endif /* UNIV_LRU_DEBUG */
  			} else {
diff --git a/mysql-innodb_overwrite_relay_log_info.patch b/mysql-innodb_overwrite_relay_log_info.patch
index 4346c98..a84ea6f 100644
--- a/mysql-innodb_overwrite_relay_log_info.patch
+++ b/mysql-innodb_overwrite_relay_log_info.patch
@@ -49,7 +49,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static my_bool	innobase_rollback_on_timeout		= FALSE;
  static my_bool	innobase_create_status_file		= FALSE;
  static my_bool	innobase_stats_on_metadata		= TRUE;
-@@ -2021,6 +2040,89 @@
+@@ -2040,6 +2059,89 @@
  	}
  #endif /* UNIV_DEBUG */
  
@@ -139,7 +139,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* Check that values don't overflow on 32-bit systems. */
  	if (sizeof(ulint) == 4) {
  		if (innobase_buffer_pool_size > UINT_MAX32) {
-@@ -2289,6 +2391,76 @@
+@@ -2308,6 +2410,76 @@
  		goto mem_free_and_error;
  	}
  
@@ -216,7 +216,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	innobase_open_tables = hash_create(200);
  	pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
  	pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
-@@ -2403,6 +2575,26 @@
+@@ -2422,6 +2594,26 @@
  		return;
  	}
  
@@ -243,7 +243,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	trx_commit_for_mysql(trx);
  }
  
-@@ -10722,6 +10914,12 @@
+@@ -10795,6 +10987,12 @@
    "don't use the datafile for normal mysqld or ibbackup! ####",
    NULL, NULL, FALSE);
  
@@ -256,7 +256,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
    "Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11140,6 +11338,7 @@
+@@ -11220,6 +11418,7 @@
    MYSQL_SYSVAR(old_blocks_pct),
    MYSQL_SYSVAR(old_blocks_time),
    MYSQL_SYSVAR(open_files),
diff --git a/mysql-innodb_pass_corrupt_table.patch b/mysql-innodb_pass_corrupt_table.patch
index d21ae6d..88c570e 100644
--- a/mysql-innodb_pass_corrupt_table.patch
+++ b/mysql-innodb_pass_corrupt_table.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c
 --- a/storage/innodb_plugin/btr/btr0btr.c	2010-08-04 02:24:19.000000000 +0900
 +++ b/storage/innodb_plugin/btr/btr0btr.c	2010-08-27 16:39:02.932248156 +0900
-@@ -137,6 +137,12 @@
+@@ -691,6 +691,12 @@
  	root_page_no = dict_index_get_page(index);
  
  	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
@@ -21,7 +21,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0
  	ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
  	     == dict_table_is_comp(index->table));
  #ifdef UNIV_BTR_DEBUG
-@@ -422,6 +428,12 @@
+@@ -977,6 +983,12 @@
  
  	root = btr_root_get(index, &mtr);
  
@@ -34,7 +34,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0
  	if (flag == BTR_N_LEAF_PAGES) {
  		seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
  
-@@ -868,6 +880,13 @@
+@@ -1431,6 +1443,13 @@
  	mtr_start(&mtr);
  
  	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
@@ -48,7 +48,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
  				    + root, space));
-@@ -890,6 +909,12 @@
+@@ -1453,6 +1472,12 @@
  	mtr_start(&mtr);
  
  	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
@@ -61,7 +61,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
  				    + root, space));
-@@ -923,6 +948,11 @@
+@@ -1486,6 +1511,11 @@
  
  	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
  
@@ -76,7 +76,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0
 diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
 --- a/storage/innodb_plugin/btr/btr0cur.c	2010-08-27 16:22:04.211409467 +0900
 +++ b/storage/innodb_plugin/btr/btr0cur.c	2010-08-27 16:39:02.934087429 +0900
-@@ -227,6 +227,11 @@
+@@ -239,6 +239,11 @@
  	case BTR_MODIFY_LEAF:
  		mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
  		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
@@ -88,7 +88,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
  #endif /* UNIV_BTR_DEBUG */
-@@ -240,6 +245,11 @@
+@@ -252,6 +257,11 @@
  			get_block = btr_block_get(space, zip_size,
  						  left_page_no,
  						  RW_X_LATCH, mtr);
@@ -100,7 +100,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  			ut_a(page_is_comp(get_block->frame)
  			     == page_is_comp(page));
-@@ -251,6 +261,11 @@
+@@ -263,6 +273,11 @@
  
  		get_block = btr_block_get(space, zip_size, page_no,
  					  RW_X_LATCH, mtr);
@@ -112,7 +112,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
  #endif /* UNIV_BTR_DEBUG */
-@@ -262,6 +277,11 @@
+@@ -274,6 +289,11 @@
  			get_block = btr_block_get(space, zip_size,
  						  right_page_no,
  						  RW_X_LATCH, mtr);
@@ -124,7 +124,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  			ut_a(page_is_comp(get_block->frame)
  			     == page_is_comp(page));
-@@ -283,6 +303,11 @@
+@@ -295,6 +315,11 @@
  			get_block = btr_block_get(space, zip_size,
  						  left_page_no, mode, mtr);
  			cursor->left_block = get_block;
@@ -136,7 +136,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  			ut_a(page_is_comp(get_block->frame)
  			     == page_is_comp(page));
-@@ -293,6 +318,11 @@
+@@ -305,6 +330,11 @@
  		}
  
  		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
@@ -148,7 +148,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  #ifdef UNIV_BTR_DEBUG
  		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
  #endif /* UNIV_BTR_DEBUG */
-@@ -524,6 +554,16 @@
+@@ -536,6 +566,16 @@
  					 rw_latch, guess, buf_mode,
  					 file, line, mtr);
  		if (block == NULL) {
@@ -165,7 +165,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  			/* This must be a search to perform an insert;
  			try insert to the insert buffer */
  
-@@ -551,6 +591,16 @@
+@@ -563,6 +603,16 @@
  
  		page = buf_block_get_frame(block);
  
@@ -182,7 +182,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  		block->check_index_page_at_flush = TRUE;
  
  		if (rw_latch != RW_NO_LATCH) {
-@@ -734,6 +784,17 @@
+@@ -746,6 +796,17 @@
  					 RW_NO_LATCH, NULL, BUF_GET,
  					 file, line, mtr);
  		page = buf_block_get_frame(block);
@@ -200,7 +200,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  		ut_ad(0 == ut_dulint_cmp(index->id,
  					 btr_page_get_index_id(page)));
  
-@@ -855,6 +916,14 @@
+@@ -867,6 +928,14 @@
  					 RW_NO_LATCH, NULL, BUF_GET,
  					 file, line, mtr);
  		page = buf_block_get_frame(block);
@@ -215,7 +215,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  		ut_ad(0 == ut_dulint_cmp(index->id,
  					 btr_page_get_index_id(page)));
  
-@@ -1171,6 +1240,12 @@
+@@ -1081,6 +1150,12 @@
  	*big_rec = NULL;
  
  	block = btr_cur_get_block(cursor);
@@ -228,7 +228,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  	page = buf_block_get_frame(block);
  	index = cursor->index;
  	zip_size = buf_block_get_zip_size(block);
-@@ -2895,6 +2970,11 @@
+@@ -2806,6 +2881,11 @@
  
  	block = btr_cur_get_block(cursor);
  
@@ -240,7 +240,7 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
  	ut_ad(page_is_leaf(buf_block_get_frame(block)));
  
  	rec = btr_cur_get_rec(cursor);
-@@ -3540,6 +3620,11 @@
+@@ -3350,6 +3430,11 @@
  
  		page = btr_cur_get_page(&cursor);
  
@@ -249,9 +249,9 @@ diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0
 +		}
 +		ut_a(page);
 +
- 		supremum = page_get_supremum_rec(page);
- 		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS && is_first_page) {
- 			/* the cursor should be the first record of the page. */
+ 		rec = page_rec_get_next(page_get_infimum_rec(page));
+ 
+ 		if (!page_rec_is_supremum(rec)) {
 diff -ruN a/storage/innodb_plugin/btr/btr0pcur.c b/storage/innodb_plugin/btr/btr0pcur.c
 --- a/storage/innodb_plugin/btr/btr0pcur.c	2010-08-04 02:24:19.000000000 +0900
 +++ b/storage/innodb_plugin/btr/btr0pcur.c	2010-08-27 16:39:02.936071298 +0900
@@ -340,7 +340,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  			if (!ready) {
  
  				return(block);
-@@ -1803,6 +1809,14 @@
+@@ -1805,6 +1811,14 @@
  		return(NULL);
  	}
  
@@ -355,7 +355,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  	block_mutex = buf_page_get_mutex_enter(bpage);
  
  	rw_lock_s_unlock(&page_hash_latch);
-@@ -2264,6 +2278,14 @@
+@@ -2280,6 +2294,14 @@
  		return(NULL);
  	}
  
@@ -370,15 +370,15 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  	switch (buf_block_get_state(block)) {
  		buf_page_t*	bpage;
  		ibool		success;
-@@ -2909,6 +2931,7 @@
+@@ -2927,6 +2949,7 @@
  	bpage->newest_modification = 0;
  	bpage->oldest_modification = 0;
  	HASH_INVALIDATE(bpage, hash);
 +	bpage->is_corrupt = FALSE;
- #ifdef UNIV_DEBUG_FILE_ACCESSES
+ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
  	bpage->file_page_was_freed = FALSE;
- #endif /* UNIV_DEBUG_FILE_ACCESSES */
-@@ -3365,7 +3388,8 @@
+ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
+@@ -3384,7 +3407,8 @@
  void
  buf_page_io_complete(
  /*=================*/
@@ -388,7 +388,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  {
  	enum buf_io_fix	io_type;
  	const ibool	uncompressed = (buf_page_get_state(bpage)
-@@ -3443,6 +3467,7 @@
+@@ -3462,6 +3486,7 @@
  				(ulong) bpage->offset);
  		}
  
@@ -396,7 +396,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  		/* From version 3.23.38 up we store the page checksum
  		to the 4 first bytes of the page end lsn field */
  
-@@ -3484,6 +3509,19 @@
+@@ -3503,6 +3528,19 @@
  			      REFMAN "forcing-innodb-recovery.html\n"
  			      "InnoDB: about forcing recovery.\n", stderr);
  
@@ -416,7 +416,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  			if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
  				fputs("InnoDB: Ending processing because of"
  				      " a corrupt database page.\n",
-@@ -3491,6 +3529,7 @@
+@@ -3510,6 +3548,7 @@
  				exit(1);
  			}
  		}
@@ -424,7 +424,7 @@ diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0
  
  		if (recv_recovery_is_on()) {
  			/* Pages must be uncompressed for crash recovery. */
-@@ -3500,8 +3539,11 @@
+@@ -3519,8 +3558,11 @@
  
  		if (uncompressed && !recv_no_ibuf_operations) {
  			ibuf_merge_or_delete_for_page(
@@ -489,7 +489,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  			goto next_loop;
  
  		cached_foreign_tables = 0;
-@@ -4593,6 +4594,11 @@
+@@ -4651,6 +4652,11 @@
  	}
  
  	do {
@@ -501,7 +501,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  		if (UNIV_LIKELY
  		    (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
  		     || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
-@@ -5320,4 +5326,42 @@
+@@ -5454,4 +5460,42 @@
  		rw_lock_free(&dict_table_stats_latches[i]);
  	}
  }
@@ -547,7 +547,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 diff -ruN a/storage/innodb_plugin/dict/dict0mem.c b/storage/innodb_plugin/dict/dict0mem.c
 --- a/storage/innodb_plugin/dict/dict0mem.c	2010-08-04 02:24:19.000000000 +0900
 +++ b/storage/innodb_plugin/dict/dict0mem.c	2010-08-27 16:39:02.945072825 +0900
-@@ -86,6 +86,8 @@
+@@ -89,6 +89,8 @@
  	/* The number of transactions that are either waiting on the
  	AUTOINC lock or have been granted the lock. */
  	table->n_waiting_or_granted_auto_inc_locks = 0;
@@ -778,7 +778,7 @@ diff -ruN a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:38:38.249059616 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:39:02.960021471 +0900
-@@ -3716,6 +3716,12 @@
+@@ -3735,6 +3735,12 @@
  		DBUG_RETURN(1);
  	}
  
@@ -791,7 +791,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* Create buffers for packing the fields of a record. Why
  	table->reclength did not work here? Obviously, because char
  	fields when packed actually became 1 byte longer, when we also
-@@ -3743,6 +3749,19 @@
+@@ -3762,6 +3768,19 @@
  	/* Get pointer to a table object in InnoDB dictionary cache */
  	ib_table = dict_table_get(norm_name, TRUE);
  	
@@ -811,7 +811,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	if (NULL == ib_table) {
  		if (is_part && retries < 10) {
  			++retries;
-@@ -4909,6 +4928,10 @@
+@@ -4928,6 +4947,10 @@
  
  	ha_statistic_increment(&SSV::ha_write_count);
  
@@ -822,7 +822,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
  		table->timestamp_field->set_time();
  
-@@ -5126,6 +5149,10 @@
+@@ -5145,6 +5168,10 @@
  func_exit:
  	innobase_active_small();
  
@@ -833,7 +833,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	DBUG_RETURN(error_result);
  }
  
-@@ -5302,6 +5329,10 @@
+@@ -5321,6 +5348,10 @@
  
  	ha_statistic_increment(&SSV::ha_update_count);
  
@@ -844,7 +844,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
  		table->timestamp_field->set_time();
  
-@@ -5391,6 +5422,10 @@
+@@ -5410,6 +5441,10 @@
  
  	innobase_active_small();
  
@@ -855,7 +855,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	DBUG_RETURN(error);
  }
  
-@@ -5412,6 +5447,10 @@
+@@ -5431,6 +5466,10 @@
  
  	ha_statistic_increment(&SSV::ha_delete_count);
  
@@ -866,7 +866,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	if (!prebuilt->upd_node) {
  		row_get_prebuilt_update_vector(prebuilt);
  	}
-@@ -5438,6 +5477,10 @@
+@@ -5457,6 +5496,10 @@
  
  	innobase_active_small();
  
@@ -877,7 +877,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	DBUG_RETURN(error);
  }
  
-@@ -5677,6 +5720,10 @@
+@@ -5696,6 +5739,10 @@
  
  	ha_statistic_increment(&SSV::ha_read_key_count);
  
@@ -888,7 +888,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	index = prebuilt->index;
  
  	if (UNIV_UNLIKELY(index == NULL)) {
-@@ -5742,6 +5789,10 @@
+@@ -5761,6 +5808,10 @@
  		ret = DB_UNSUPPORTED;
  	}
  
@@ -899,7 +899,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	switch (ret) {
  	case DB_SUCCESS:
  		error = 0;
-@@ -5857,6 +5908,10 @@
+@@ -5876,6 +5927,10 @@
  {
  	DBUG_ENTER("change_active_index");
  
@@ -910,7 +910,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	ut_ad(user_thd == ha_thd());
  	ut_a(prebuilt->trx == thd_to_trx(user_thd));
  
-@@ -5947,6 +6002,10 @@
+@@ -5966,6 +6021,10 @@
  
  	DBUG_ENTER("general_fetch");
  
@@ -921,7 +921,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	ut_a(prebuilt->trx == thd_to_trx(user_thd));
  
  	innodb_srv_conc_enter_innodb(prebuilt->trx);
-@@ -5956,6 +6015,10 @@
+@@ -5975,6 +6034,10 @@
  
  	innodb_srv_conc_exit_innodb(prebuilt->trx);
  
@@ -932,7 +932,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	switch (ret) {
  	case DB_SUCCESS:
  		error = 0;
-@@ -7214,6 +7277,10 @@
+@@ -7233,6 +7296,10 @@
  		DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
  	}
  
@@ -943,7 +943,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* Truncate the table in InnoDB */
  
  	error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
-@@ -7222,6 +7289,10 @@
+@@ -7241,6 +7308,10 @@
  		goto fallback;
  	}
  
@@ -954,7 +954,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	error = convert_error_code_to_mysql(error, prebuilt->table->flags,
  					    NULL);
  
-@@ -7734,6 +7805,16 @@
+@@ -7753,6 +7824,16 @@
  	return(ranges + (double) rows / (double) total_rows * time_for_scan);
  }
  
@@ -971,7 +971,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  /*********************************************************************//**
  Calculates the key number used inside MySQL for an Innobase index. We will
  first check the "index translation table" for a match of the index to get
-@@ -7855,7 +7936,7 @@
+@@ -7933,7 +8014,7 @@
  	ib_table = prebuilt->table;
  
  	if (flag & HA_STATUS_TIME) {
@@ -980,7 +980,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  			/* In sql_show we call with this flag: update
  			then statistics so that they are up-to-date */
  
-@@ -8146,10 +8227,18 @@
+@@ -8223,10 +8304,18 @@
  	THD*		thd,		/*!< in: connection thread handle */
  	HA_CHECK_OPT*	check_opt)	/*!< in: currently ignored */
  {
@@ -999,7 +999,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	return(0);
  }
  
-@@ -8331,6 +8420,10 @@
+@@ -8408,6 +8497,10 @@
  		my_error(ER_QUERY_INTERRUPTED, MYF(0));
  	}
  
@@ -1010,7 +1010,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
  }
  
-@@ -9056,6 +9149,10 @@
+@@ -9133,6 +9226,10 @@
  
  	update_thd(thd);
  
@@ -1021,7 +1021,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
  		ut_print_timestamp(stderr);
  		fprintf(stderr,
-@@ -11500,6 +11597,14 @@
+@@ -11565,6 +11662,14 @@
    "0 (the default) disables automatic dumps.",
    NULL, NULL, 0, 0, UINT_MAX32, 0);
  
@@ -1036,7 +1036,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static struct st_mysql_sys_var* innobase_system_variables[]= {
    MYSQL_SYSVAR(additional_mem_pool_size),
    MYSQL_SYSVAR(autoextend_increment),
-@@ -11585,6 +11690,7 @@
+@@ -11650,6 +11755,7 @@
    MYSQL_SYSVAR(io_capacity),
    MYSQL_SYSVAR(auto_lru_dump),
    MYSQL_SYSVAR(use_purge_thread),
@@ -1123,7 +1123,7 @@ diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/incl
  					in the buffer pool */
  	/* @} */
 +	ibool		is_corrupt;
- # ifdef UNIV_DEBUG_FILE_ACCESSES
+ # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
  	ibool		file_page_was_freed;
  					/*!< this is set to TRUE when fsp
 diff -ruN a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
@@ -1154,7 +1154,7 @@ diff -ruN a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/inc
 diff -ruN a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h
 --- a/storage/innodb_plugin/include/dict0dict.h	2010-08-27 16:22:04.264988090 +0900
 +++ b/storage/innodb_plugin/include/dict0dict.h	2010-08-27 16:39:03.011025333 +0900
-@@ -1199,6 +1199,15 @@
+@@ -1206,6 +1206,15 @@
  dict_close(void);
  /*============*/
  
@@ -1173,7 +1173,7 @@ diff -ruN a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/in
 diff -ruN a/storage/innodb_plugin/include/dict0mem.h b/storage/innodb_plugin/include/dict0mem.h
 --- a/storage/innodb_plugin/include/dict0mem.h	2010-08-04 02:24:19.000000000 +0900
 +++ b/storage/innodb_plugin/include/dict0mem.h	2010-08-27 16:39:03.013021149 +0900
-@@ -560,6 +560,7 @@
+@@ -573,6 +573,7 @@
  				the AUTOINC lock on this table. */
  				/* @} */
  	/*----------------------*/
@@ -1268,7 +1268,7 @@ diff -ruN a/storage/innodb_plugin/include/page0zip.h b/storage/innodb_plugin/inc
 diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
 --- a/storage/innodb_plugin/include/srv0srv.h	2010-08-27 16:38:38.275010935 +0900
 +++ b/storage/innodb_plugin/include/srv0srv.h	2010-08-27 16:39:03.030004790 +0900
-@@ -230,6 +230,7 @@
+@@ -231,6 +231,7 @@
  extern ulint	srv_adaptive_checkpoint;
  
  extern ulint	srv_expand_import;
@@ -1343,7 +1343,7 @@ diff -ruN a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0
 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
 --- a/storage/innodb_plugin/srv/srv0srv.c	2010-08-27 16:38:38.286989546 +0900
 +++ b/storage/innodb_plugin/srv/srv0srv.c	2010-08-27 16:39:03.048990992 +0900
-@@ -402,6 +402,7 @@
+@@ -406,6 +406,7 @@
  UNIV_INTERN ulint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
  
  UNIV_INTERN ulint	srv_expand_import = 0; /* 0:disable 1:enable */
@@ -1354,7 +1354,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
 diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
 --- a/storage/innodb_plugin/srv/srv0start.c	2010-08-27 16:38:38.290021700 +0900
 +++ b/storage/innodb_plugin/srv/srv0start.c	2010-08-27 16:39:03.052021423 +0900
-@@ -1994,6 +1994,13 @@
+@@ -2000,6 +2000,13 @@
  
  	os_fast_mutex_free(&srv_os_test_mutex);
  
diff --git a/mysql-innodb_purge_thread.patch b/mysql-innodb_purge_thread.patch
index fcf951a..5796e33 100644
--- a/mysql-innodb_purge_thread.patch
+++ b/mysql-innodb_purge_thread.patch
@@ -8,19 +8,19 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:23:31.022060427 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:25:49.004020662 +0900
-@@ -10987,6 +10987,11 @@
+@@ -11064,6 +11064,11 @@
    "Output statistics of recovery process after it.",
    NULL, NULL, FALSE);
  
 +static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
 +  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 +  "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
-+  NULL, NULL, 0, 0, 64, 0);
++  NULL, NULL, 0, 0, UNIV_MAX_PARALLELISM, 0);
 +
  static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
    "During InnoDB crash recovery on slave overwrite relay-log.info "
-@@ -11510,6 +11515,7 @@
+@@ -11575,6 +11580,7 @@
  #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
    MYSQL_SYSVAR(read_ahead_threshold),
    MYSQL_SYSVAR(io_capacity),
@@ -50,7 +50,7 @@ diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/incl
  extern ibool	srv_auto_extend_last_data_file;
  extern ulint	srv_last_file_size_max;
  extern char**	srv_log_group_home_dirs;
-@@ -407,6 +409,8 @@
+@@ -421,6 +423,8 @@
  	SRV_RECOVERY,	/**< threads finishing a recovery */
  	SRV_INSERT,	/**< thread flushing the insert buffer to disk */
  #endif
@@ -59,7 +59,7 @@ diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/incl
  	SRV_MASTER	/**< the master thread, (whose type number must
  			be biggest) */
  };
-@@ -480,6 +484,21 @@
+@@ -494,6 +498,21 @@
  /*==============*/
  	void*	arg);	/*!< in: a dummy parameter required by
  			os_thread_create */
@@ -154,7 +154,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  /* if TRUE, then we auto-extend the last data file */
  UNIV_INTERN ibool	srv_auto_extend_last_data_file	= FALSE;
  /* if != 0, this tells the max size auto-extending may increase the
-@@ -2626,10 +2628,10 @@
+@@ -2639,10 +2641,10 @@
  	srv_main_thread_process_no = os_proc_get_number();
  	srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
  
@@ -166,7 +166,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	srv_n_threads_active[SRV_MASTER]++;
  
  	mutex_exit(&kernel_mutex);
-@@ -3087,6 +3089,7 @@
+@@ -3100,6 +3102,7 @@
  	/* Flush logs if needed */
  	srv_sync_log_buffer_in_background();
  
@@ -174,7 +174,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	/* We run a full purge every 10 seconds, even if the server
  	were active */
  	do {
-@@ -3103,6 +3106,7 @@
+@@ -3116,6 +3119,7 @@
  		srv_sync_log_buffer_in_background();
  
  	} while (n_pages_purged);
@@ -182,7 +182,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	srv_main_thread_op_info = "flushing buffer pool pages";
  
-@@ -3171,6 +3175,7 @@
+@@ -3184,6 +3188,7 @@
  		os_thread_sleep(100000);
  	}
  
@@ -190,7 +190,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	srv_main_thread_op_info = "purging";
  
  	/* Run a full purge */
-@@ -3187,6 +3192,7 @@
+@@ -3200,6 +3205,7 @@
  		srv_sync_log_buffer_in_background();
  
  	} while (n_pages_purged);
@@ -198,7 +198,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  
  	srv_main_thread_op_info = "reserving kernel mutex";
  
-@@ -3339,3 +3345,143 @@
+@@ -3352,3 +3358,143 @@
  
  	OS_THREAD_DUMMY_RETURN;	/* Not reached, avoid compiler warning */
  }
@@ -350,14 +350,14 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  
  /** io_handler_thread parameters for thread identification */
 -static ulint		n[SRV_MAX_N_IO_THREADS + 6];
-+static ulint		n[SRV_MAX_N_IO_THREADS + 6 + 64];
++static ulint		n[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
  /** io_handler_thread identifiers */
 -static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 6];
-+static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64];
++static os_thread_id_t	thread_ids[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
  
  /** We use this mutex to test the return value of pthread_mutex_trylock
     on successful locking. HP-UX does NOT return 0, though Linux et al do. */
-@@ -1719,6 +1719,20 @@
+@@ -1725,6 +1725,20 @@
  
  	os_thread_create(&srv_master_thread, NULL, thread_ids
  			 + (1 + SRV_MAX_N_IO_THREADS));
diff --git a/mysql-innodb_separate_doublewrite.patch b/mysql-innodb_separate_doublewrite.patch
index 50b0a5e..0d6e1d6 100644
--- a/mysql-innodb_separate_doublewrite.patch
+++ b/mysql-innodb_separate_doublewrite.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
 --- a/storage/innodb_plugin/buf/buf0buf.c	2010-08-27 16:32:40.292412102 +0900
 +++ b/storage/innodb_plugin/buf/buf0buf.c	2010-08-27 16:37:55.358105738 +0900
-@@ -3412,7 +3412,8 @@
+@@ -3431,7 +3431,8 @@
  		read_space_id = mach_read_from_4(
  			frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
  
@@ -348,7 +348,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  /* Note: This variable can be set to on/off and any of the supported
  file formats in the configuration file, but can only be set to any
-@@ -2248,6 +2249,8 @@
+@@ -2267,6 +2268,8 @@
  		goto error;
  	}
  
@@ -357,7 +357,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	srv_extra_undoslots = (ibool) innobase_extra_undoslots;
  
  	srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
-@@ -11334,6 +11337,11 @@
+@@ -11392,6 +11395,11 @@
    "Path to individual files and their sizes.",
    NULL, NULL, NULL);
  
@@ -369,7 +369,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
    PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
    "The AUTOINC lock modes supported by InnoDB:               "
-@@ -11500,6 +11508,7 @@
+@@ -11565,6 +11573,7 @@
    MYSQL_SYSVAR(commit_concurrency),
    MYSQL_SYSVAR(concurrency_tickets),
    MYSQL_SYSVAR(data_file_path),
@@ -529,7 +529,7 @@ diff -ruN a/storage/innodb_plugin/include/trx0sys.ic b/storage/innodb_plugin/inc
 diff -ruN a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
 --- a/storage/innodb_plugin/row/row0mysql.c	2010-08-27 16:22:04.287058274 +0900
 +++ b/storage/innodb_plugin/row/row0mysql.c	2010-08-27 16:37:55.410993060 +0900
-@@ -3365,7 +3365,7 @@
+@@ -3391,7 +3391,7 @@
  		/* Do not drop possible .ibd tablespace if something went
  		wrong: we do not want to delete valuable data of the user */
  
@@ -720,7 +720,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  	ibool		log_file_created;
  	ibool		log_created	= FALSE;
  	ibool		log_opened	= FALSE;
-@@ -1401,6 +1540,7 @@
+@@ -1407,6 +1546,7 @@
  	}
  
  	err = open_or_create_data_files(&create_new_db,
@@ -728,7 +728,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  #ifdef UNIV_LOG_ARCHIVE
  					&min_arch_log_no, &max_arch_log_no,
  #endif /* UNIV_LOG_ARCHIVE */
-@@ -1524,6 +1664,15 @@
+@@ -1530,6 +1670,15 @@
  		mtr_commit(&mtr);
  
  		trx_sys_create();
@@ -744,7 +744,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  		dict_create();
  		srv_startup_is_before_trx_rollback_phase = FALSE;
  
-@@ -1561,6 +1710,13 @@
+@@ -1567,6 +1716,13 @@
  		recv_recovery_from_archive_finish();
  #endif /* UNIV_LOG_ARCHIVE */
  	} else {
@@ -758,7 +758,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/sr
  
  		/* Check if we support the max format that is stamped
  		on the system tablespace. 
-@@ -1647,6 +1803,17 @@
+@@ -1653,6 +1809,17 @@
  		we have finished the recovery process so that the
  		image of TRX_SYS_PAGE_NO is not stale. */
  		trx_sys_file_format_tag_init();
diff --git a/mysql-innodb_show_enhancements.patch b/mysql-innodb_show_enhancements.patch
index f1235b9..7fd80b8 100644
--- a/mysql-innodb_show_enhancements.patch
+++ b/mysql-innodb_show_enhancements.patch
@@ -30,7 +30,7 @@ diff -ruN a/storage/innodb_plugin/Makefile.in b/storage/innodb_plugin/Makefile.i
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-06 23:07:12.000000000 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 15:22:39.000000000 +0900
-@@ -11040,7 +11040,8 @@
+@@ -11121,7 +11121,8 @@
  i_s_innodb_cmp,
  i_s_innodb_cmp_reset,
  i_s_innodb_cmpmem,
diff --git a/mysql-innodb_show_lock_name.patch b/mysql-innodb_show_lock_name.patch
index 71a5d16..8a88cac 100644
--- a/mysql-innodb_show_lock_name.patch
+++ b/mysql-innodb_show_lock_name.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:29:12.539982446 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:29:24.322059309 +0900
-@@ -9246,8 +9246,8 @@
+@@ -9323,8 +9323,8 @@
  			rw_lock_wait_time += mutex->lspent_time;
  		}
  #else /* UNIV_DEBUG */
@@ -19,7 +19,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
  				     (ulong) mutex->count_os_wait);
  
-@@ -9262,9 +9262,8 @@
+@@ -9339,9 +9339,8 @@
  
  	if (block_mutex) {
  		buf1len = (uint) my_snprintf(buf1, sizeof buf1,
@@ -31,7 +31,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		buf2len = (uint) my_snprintf(buf2, sizeof buf2,
  					     "os_waits=%lu",
  					     (ulong) block_mutex_oswait_count);
-@@ -9293,8 +9292,8 @@
+@@ -9370,8 +9369,8 @@
  			continue;
  		}
  
@@ -42,7 +42,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
  				      (ulong) lock->count_os_wait);
  
-@@ -9308,9 +9307,8 @@
+@@ -9385,9 +9384,8 @@
  
  	if (block_lock) {
  		buf1len = (uint) my_snprintf(buf1, sizeof buf1,
@@ -99,7 +99,7 @@ diff -ruN a/storage/innodb_plugin/include/sync0rw.h b/storage/innodb_plugin/incl
  /******************************************************************//**
  Calling this function is obligatory only if the memory buffer containing
  the rw-lock is freed. Removes an rw-lock object from the global list. The
-@@ -541,7 +541,8 @@
+@@ -542,7 +542,8 @@
  	ulint	level;		/*!< Level in the global latching order. */
  #endif /* UNIV_SYNC_DEBUG */
  	ulint count_os_wait;	/*!< Count of os_waits. May not be accurate */
@@ -109,7 +109,7 @@ diff -ruN a/storage/innodb_plugin/include/sync0rw.h b/storage/innodb_plugin/incl
          /* last s-lock file/line is not guaranteed to be correct */
  	const char*	last_s_file_name;/*!< File name where last s-locked */
  	const char*	last_x_file_name;/*!< File name where last x-locked */
-@@ -552,7 +553,7 @@
+@@ -553,7 +554,7 @@
  				are at the start of this struct, thus we can
  				peek this field without causing much memory
  				bus traffic */
@@ -245,7 +245,7 @@ diff -ruN a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sy
  # endif
  #endif /* INNODB_RW_LOCKS_USE_ATOMICS */
  
-@@ -269,8 +270,7 @@
+@@ -272,8 +273,7 @@
  
  	ut_d(lock->magic_n = RW_LOCK_MAGIC_N);
  
@@ -255,7 +255,7 @@ diff -ruN a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sy
  
  	lock->count_os_wait = 0;
  	lock->last_s_file_name = "not yet reserved";
-@@ -390,10 +390,10 @@
+@@ -393,10 +393,10 @@
  	if (srv_print_latch_waits) {
  		fprintf(stderr,
  			"Thread %lu spin wait rw-s-lock at %p"
@@ -268,7 +268,7 @@ diff -ruN a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sy
  	}
  
  	/* We try once again to obtain the lock */
-@@ -426,10 +426,9 @@
+@@ -429,10 +429,9 @@
  		if (srv_print_latch_waits) {
  			fprintf(stderr,
  				"Thread %lu OS wait rw-s-lock at %p"
@@ -281,7 +281,7 @@ diff -ruN a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sy
  		}
  
  		/* these stats may not be accurate */
-@@ -648,9 +647,9 @@
+@@ -651,9 +650,9 @@
  	if (srv_print_latch_waits) {
  		fprintf(stderr,
  			"Thread %lu spin wait rw-x-lock at %p"
@@ -293,7 +293,7 @@ diff -ruN a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sy
  	}
  
  	sync_array_reserve_cell(sync_primary_wait_array,
-@@ -671,9 +670,9 @@
+@@ -674,9 +673,9 @@
  	if (srv_print_latch_waits) {
  		fprintf(stderr,
  			"Thread %lu OS wait for rw-x-lock at %p"
diff --git a/mysql-innodb_show_status.patch b/mysql-innodb_show_status.patch
index 2fbaf51..1960206 100644
--- a/mysql-innodb_show_status.patch
+++ b/mysql-innodb_show_status.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
 --- a/storage/innodb_plugin/buf/buf0buf.c	2010-04-06 23:07:12.000000000 +0900
 +++ b/storage/innodb_plugin/buf/buf0buf.c	2010-04-29 15:28:56.000000000 +0900
-@@ -3878,14 +3878,16 @@
+@@ -3897,14 +3897,16 @@
  	buf_pool_mutex_enter();
  
  	fprintf(file,
@@ -67,7 +67,7 @@ diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 15:28:20.000000000 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 15:28:56.000000000 +0900
-@@ -10748,6 +10748,16 @@
+@@ -10821,6 +10821,16 @@
    "Force InnoDB to not use next-key locking, to use only row-level locking.",
    NULL, NULL, FALSE);
  
@@ -84,7 +84,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  #ifdef UNIV_LOG_ARCHIVE
  static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
    PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -10930,7 +10940,7 @@
+@@ -11003,7 +11013,7 @@
  
  static MYSQL_SYSVAR_STR(version, innodb_version_str,
    PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
@@ -93,7 +93,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
    PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11008,6 +11018,8 @@
+@@ -11089,6 +11099,8 @@
    MYSQL_SYSVAR(thread_concurrency),
    MYSQL_SYSVAR(thread_sleep_delay),
    MYSQL_SYSVAR(autoinc_lock_mode),
@@ -219,7 +219,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  /** Maximum number of times allowed to conditionally acquire
  mutex before switching to blocking wait on the mutex */
  #define MAX_MUTEX_NOWAIT	20
-@@ -1700,6 +1703,13 @@
+@@ -1705,6 +1708,13 @@
  	ulint	n_reserved;
  	ibool	ret;
  
@@ -233,7 +233,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	mutex_enter(&srv_innodb_monitor_mutex);
  
  	current_time = time(NULL);
-@@ -1748,31 +1758,6 @@
+@@ -1753,31 +1763,6 @@
  
  	mutex_exit(&dict_foreign_err_mutex);
  
@@ -265,7 +265,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	fputs("--------\n"
  	      "FILE I/O\n"
  	      "--------\n", file);
-@@ -1803,10 +1788,84 @@
+@@ -1808,10 +1793,84 @@
  	      "BUFFER POOL AND MEMORY\n"
  	      "----------------------\n", file);
  	fprintf(file,
@@ -354,7 +354,7 @@ diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0
  	fprintf(file, "Dictionary memory allocated " ULINTPF "\n",
  		dict_sys->size);
  
-@@ -1865,6 +1924,31 @@
+@@ -1870,6 +1929,31 @@
  	srv_n_rows_deleted_old = srv_n_rows_deleted;
  	srv_n_rows_read_old = srv_n_rows_read;
  
diff --git a/mysql-innodb_show_sys_tables.patch b/mysql-innodb_show_sys_tables.patch
index 57f98b7..39ab959 100644
--- a/mysql-innodb_show_sys_tables.patch
+++ b/mysql-innodb_show_sys_tables.patch
@@ -8,7 +8,7 @@
 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
 --- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:45:46.194411503 +0900
 +++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:49:26.171990559 +0900
-@@ -11806,6 +11806,9 @@
+@@ -11871,6 +11871,9 @@
  i_s_innodb_table_stats,
  i_s_innodb_index_stats,
  i_s_innodb_admin_command,
@@ -29,7 +29,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
  #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
  }
  
-@@ -3111,6 +3112,664 @@
+@@ -3111,6 +3112,674 @@
  	STRUCT_FLD(deinit, i_s_common_deinit),
  	STRUCT_FLD(version, 0x0100 /* 1.0 */),
  	STRUCT_FLD(status_vars, NULL),
@@ -201,6 +201,14 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	 STRUCT_FLD(old_name,		""),
 +	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
 +
++	{STRUCT_FLD(field_name,		"NON_NULL_VALS"),
++	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
++	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
++	 STRUCT_FLD(value,		0),
++	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
 +	END_OF_ST_FIELD_INFO
 +};
 +
@@ -469,6 +477,9 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +{
 +	int	status;
 +	int	field;
++	ulint	n_fields;
++
++	n_fields = rec_get_n_fields_old(rec);
 +
 +	/* INDEX_ID */
 +	field = dict_index_get_nth_col_pos(index, 0);
@@ -488,6 +499,16 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	if (status) {
 +		return status;
 +	}
++	/* NON_NULL_VALS */
++	if (n_fields < 6) {
++		table->field[3]->set_null();
++	} else {
++		field = dict_index_get_nth_col_pos(index, 3);
++		status = copy_id_field(table, 3, rec, field);
++		if (status) {
++			return status;
++		}
++	}
 +
 +	return 0;
 +}
@@ -551,15 +572,14 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +		rec = btr_pcur_get_rec(&pcur);
 +		if (!btr_pcur_is_on_user_rec(&pcur)) {
 +			/* end of index */
-+			btr_pcur_close(&pcur);
-+			mtr_commit(&mtr);
 +			break;
 +		}
++
++		btr_pcur_store_position(&pcur, &mtr);
++
 +		if (rec_get_deleted_flag(rec, 0)) {
 +			/* record marked as deleted */
-+			btr_pcur_close(&pcur);
-+			mtr_commit(&mtr);
-+			continue;
++			goto next_record;
 +		}
 +
 +		if (id == 0) {
@@ -570,33 +590,23 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +			status = copy_sys_stats_rec(table, index, rec);
 +		}
 +		if (status) {
-+			btr_pcur_close(&pcur);
-+			mtr_commit(&mtr);
 +			break;
 +		}
 +
-+#if 0
-+		btr_pcur_store_position(&pcur, &mtr);
-+		mtr_commit(&mtr);
-+
 +		status = schema_table_store_record(thd, table);
 +		if (status) {
-+			btr_pcur_close(&pcur);
 +			break;
 +		}
++next_record:
++		mtr_commit(&mtr);
 +
 +		mtr_start(&mtr);
 +		btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
-+#else
-+		status = schema_table_store_record(thd, table);
-+		if (status) {
-+			btr_pcur_close(&pcur);
-+			mtr_commit(&mtr);
-+			break;
-+		}
-+#endif
 +	}
 +
++	btr_pcur_close(&pcur);
++	mtr_commit(&mtr);
++
 +	mutex_exit(&(dict_sys->mutex));
 +
 +	DBUG_RETURN(status);
@@ -652,7 +662,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
 +	STRUCT_FLD(info, &i_s_info),
 +	STRUCT_FLD(name, "INNODB_SYS_TABLES"),
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +	STRUCT_FLD(descr, "InnoDB SYS_TABLES table"),
 +	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
 +	STRUCT_FLD(init, i_s_innodb_sys_tables_init),
@@ -668,7 +678,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
 +	STRUCT_FLD(info, &i_s_info),
 +	STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +	STRUCT_FLD(descr, "InnoDB SYS_INDEXES table"),
 +	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
 +	STRUCT_FLD(init, i_s_innodb_sys_indexes_init),
@@ -684,7 +694,7 @@ diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler
 +	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
 +	STRUCT_FLD(info, &i_s_info),
 +	STRUCT_FLD(name, "INNODB_SYS_STATS"),
-+	STRUCT_FLD(author, plugin_author),
++	STRUCT_FLD(author, "Percona"),
 +	STRUCT_FLD(descr, "InnoDB SYS_STATS table"),
 +	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
 +	STRUCT_FLD(init, i_s_innodb_sys_stats_init),
diff --git a/mysql-innodb_stats.patch b/mysql-innodb_stats.patch
index 5122409..e6fa727 100644
--- a/mysql-innodb_stats.patch
+++ b/mysql-innodb_stats.patch
@@ -5,401 +5,6 @@
 #!!! notice !!!
 # Any small change to this file in the main branch
 # should be done or reviewed by the maintainer!
-diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
---- a/storage/innodb_plugin/btr/btr0cur.c	2010-08-27 16:13:11.049975230 +0900
-+++ b/storage/innodb_plugin/btr/btr0cur.c	2010-08-27 16:16:49.201984615 +0900
-@@ -892,6 +892,108 @@
- 	}
- }
- 
-+/**********************************************************************//**
-+Positions a cursor at a randomly chosen position within a B-tree
-+after the given path
-+ at return TRUE if the position is at the first page, and cursor must point
-+        the first record for used by the caller.*/
-+UNIV_INTERN
-+ibool
-+btr_cur_open_at_rnd_pos_after_path(
-+/*====================*/
-+	dict_index_t*	index,		/*!< in: index */
-+	ulint		latch_mode,	/*!< in: BTR_SEARCH_LEAF, ... */
-+	btr_path_t*	first_rec_path,
-+	btr_cur_t*	cursor,		/*!< in/out: B-tree cursor */
-+	mtr_t*		mtr)		/*!< in: mtr */
-+{
-+	page_cur_t*	page_cursor;
-+	btr_path_t*	slot;
-+	ibool		is_first_rec	= TRUE;
-+	ulint		page_no;
-+	ulint		space;
-+	ulint		zip_size;
-+	ulint		height;
-+	rec_t*		node_ptr;
-+	mem_heap_t*	heap		= NULL;
-+	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
-+	ulint*		offsets		= offsets_;
-+	rec_offs_init(offsets_);
-+
-+	if (latch_mode == BTR_MODIFY_TREE) {
-+		mtr_x_lock(dict_index_get_lock(index), mtr);
-+	} else {
-+		mtr_s_lock(dict_index_get_lock(index), mtr);
-+	}
-+
-+	page_cursor = btr_cur_get_page_cur(cursor);
-+	cursor->index = index;
-+
-+	space = dict_index_get_space(index);
-+	zip_size = dict_table_zip_size(index->table);
-+	page_no = dict_index_get_page(index);
-+
-+	height = ULINT_UNDEFINED;
-+	slot = first_rec_path;
-+
-+	for (;;) {
-+		buf_block_t*	block;
-+		page_t*		page;
-+
-+		block = buf_page_get_gen(space, zip_size, page_no,
-+					 RW_NO_LATCH, NULL, BUF_GET,
-+					 __FILE__, __LINE__, mtr);
-+		page = buf_block_get_frame(block);
-+		ut_ad(0 == ut_dulint_cmp(index->id,
-+					 btr_page_get_index_id(page)));
-+
-+		if (height == ULINT_UNDEFINED) {
-+			/* We are in the root node */
-+
-+			height = btr_page_get_level(page, mtr);
-+		}
-+
-+		if (height == 0) {
-+			btr_cur_latch_leaves(page, space, zip_size, page_no,
-+					     latch_mode, cursor, mtr);
-+		}
-+
-+		if (is_first_rec && slot->nth_rec != ULINT_UNDEFINED) {
-+			if (height == 0) {
-+				/* must open the first rec */
-+				page_cur_open_on_nth_user_rec(block, page_cursor, slot->nth_rec);
-+			} else {
-+				is_first_rec = page_cur_open_on_rnd_user_rec_after_nth(block,
-+								page_cursor, slot->nth_rec);
-+			}
-+		} else {
-+			is_first_rec = FALSE;
-+			page_cur_open_on_rnd_user_rec(block, page_cursor);
-+		}
-+
-+		if (height == 0) {
-+			break;
-+		}
-+
-+		ut_ad(height > 0);
-+
-+		height--;
-+		slot++;
-+
-+		node_ptr = page_cur_get_rec(page_cursor);
-+		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
-+					  ULINT_UNDEFINED, &heap);
-+		/* Go to the child node */
-+		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
-+	}
-+
-+	if (UNIV_LIKELY_NULL(heap)) {
-+		mem_heap_free(heap);
-+	}
-+
-+	return (is_first_rec);
-+}
-+
- /*==================== B-TREE INSERT =========================*/
- 
- /*************************************************************//**
-@@ -3201,6 +3303,154 @@
- }
- 
- /*******************************************************************//**
-+Estimates the number of pages which have not null value of the key of n_cols.
-+ at return	estimated number of pages */
-+UNIV_INTERN
-+ulint
-+btr_estimate_n_pages_not_null(
-+/*=========================*/
-+	dict_index_t*	index,	/*!< in: index */
-+	ulint		n_cols,	/*!< in: The cols should be not null */
-+	btr_path_t*	path1)	/*!< in: path1[BTR_PATH_ARRAY_N_SLOTS] */
-+{
-+	dtuple_t*	tuple1;
-+	btr_path_t	path2[BTR_PATH_ARRAY_N_SLOTS];
-+	btr_cur_t	cursor;
-+	btr_path_t*	slot1;
-+	btr_path_t*	slot2;
-+	ibool		diverged;
-+	ibool		diverged_lot;
-+	ulint		divergence_level;
-+	ulint		n_pages;
-+	ulint		i;
-+	mtr_t		mtr;
-+	mem_heap_t*	heap;
-+
-+	heap = mem_heap_create(n_cols * sizeof(dfield_t)
-+				+ sizeof(dtuple_t));
-+
-+	/* make tuple1 (NULL,NULL,,,) from n_cols */
-+	tuple1 = dtuple_create(heap, n_cols);
-+	dict_index_copy_types(tuple1, index, n_cols);
-+
-+	for (i = 0; i < n_cols; i++) {
-+		dfield_set_null(dtuple_get_nth_field(tuple1, i));
-+	}
-+
-+	mtr_start(&mtr);
-+
-+	cursor.path_arr = path1;
-+
-+	btr_cur_search_to_nth_level(index, 0, tuple1, PAGE_CUR_G,
-+				    BTR_SEARCH_LEAF | BTR_ESTIMATE,
-+				    &cursor, 0, __FILE__, __LINE__, &mtr);
-+
-+	mtr_commit(&mtr);
-+
-+
-+
-+	mtr_start(&mtr);
-+
-+	cursor.path_arr = path2;
-+
-+	btr_cur_open_at_index_side(FALSE, index,
-+				   BTR_SEARCH_LEAF | BTR_ESTIMATE,
-+				   &cursor, &mtr);
-+
-+	mtr_commit(&mtr);
-+
-+	mem_heap_free(heap);
-+
-+	/* We have the path information for the range in path1 and path2 */
-+
-+	n_pages = 1;
-+	diverged = FALSE;	    /* This becomes true when the path is not
-+				    the same any more */
-+	diverged_lot = FALSE;	    /* This becomes true when the paths are
-+				    not the same or adjacent any more */
-+	divergence_level = 1000000; /* This is the level where paths diverged
-+				    a lot */
-+	for (i = 0; ; i++) {
-+		ut_ad(i < BTR_PATH_ARRAY_N_SLOTS);
-+
-+		slot1 = path1 + i;
-+		slot2 = path2 + i;
-+
-+		if ((slot1 + 1)->nth_rec == ULINT_UNDEFINED
-+		    || (slot2 + 1)->nth_rec == ULINT_UNDEFINED) {
-+
-+			if (i > divergence_level + 1) {
-+				/* In trees whose height is > 1 our algorithm
-+				tends to underestimate: multiply the estimate
-+				by 2: */
-+
-+				n_pages = n_pages * 2;
-+			}
-+
-+			/* Do not estimate the number of rows in the range
-+			to over 1 / 2 of the estimated rows in the whole
-+			table */
-+
-+			if (n_pages > index->stat_n_leaf_pages / 2) {
-+				n_pages = index->stat_n_leaf_pages / 2;
-+
-+				/* If there are just 0 or 1 rows in the table,
-+				then we estimate all rows are in the range */
-+
-+				if (n_pages == 0) {
-+					n_pages = index->stat_n_leaf_pages;
-+				}
-+			}
-+
-+			return(n_pages);
-+		}
-+
-+		if (!diverged && slot1->nth_rec != slot2->nth_rec) {
-+
-+			diverged = TRUE;
-+
-+			if (slot1->nth_rec < slot2->nth_rec) {
-+				n_pages = slot2->nth_rec - slot1->nth_rec;
-+
-+				if (n_pages > 1) {
-+					diverged_lot = TRUE;
-+					divergence_level = i;
-+				}
-+			} else {
-+				/* Maybe the tree has changed between
-+				searches */
-+
-+				return(10);
-+			}
-+
-+		} else if (diverged && !diverged_lot) {
-+
-+			if (slot1->nth_rec < slot1->n_recs
-+			    || slot2->nth_rec > 1) {
-+
-+				diverged_lot = TRUE;
-+				divergence_level = i;
-+
-+				n_pages = 0;
-+
-+				if (slot1->nth_rec < slot1->n_recs) {
-+					n_pages += slot1->n_recs
-+						- slot1->nth_rec;
-+				}
-+
-+				if (slot2->nth_rec > 1) {
-+					n_pages += slot2->nth_rec - 1;
-+				}
-+			}
-+		} else if (diverged_lot) {
-+
-+			n_pages = (n_pages * (slot1->n_recs + slot2->n_recs))
-+				/ 2;
-+		}
-+	}
-+}
-+
-+/*******************************************************************//**
- Estimates the number of different key values in a given index, for
- each n-column prefix of the index where n <= dict_index_get_n_unique(index).
- The estimates are stored in the array index->stat_n_diff_key_vals. */
-@@ -3229,18 +3479,38 @@
- 	ulint		offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
- 	ulint*		offsets_rec	= offsets_rec_;
- 	ulint*		offsets_next_rec= offsets_next_rec_;
-+	ulint		stats_method	= srv_stats_method;
-+	btr_path_t	first_rec_path[BTR_PATH_ARRAY_N_SLOTS];
-+	ulint		effective_pages; /* effective leaf pages */
- 	rec_offs_init(offsets_rec_);
- 	rec_offs_init(offsets_next_rec_);
- 
- 	n_cols = dict_index_get_n_unique(index);
- 
-+	if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-+		/* estimate effective pages and path for the first effective record */
-+		/* TODO: make it work also for n_cols > 1. */
-+		effective_pages = btr_estimate_n_pages_not_null(index, 1 /*k*/, first_rec_path);
-+
-+		if (!effective_pages) {
-+			for (j = 0; j <= n_cols; j++) {
-+				index->stat_n_diff_key_vals[j] = (ib_int64_t)index->stat_n_leaf_pages;
-+			}
-+			return;
-+		} else if (effective_pages > index->stat_n_leaf_pages) {
-+			effective_pages = index->stat_n_leaf_pages;
-+		}
-+	} else {
-+		effective_pages = index->stat_n_leaf_pages;
-+	}
-+
- 	n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
- 
- 	/* It makes no sense to test more pages than are contained
- 	in the index, thus we lower the number if it is too high */
--	if (srv_stats_sample_pages > index->stat_index_size) {
--		if (index->stat_index_size > 0) {
--			n_sample_pages = index->stat_index_size;
-+	if (srv_stats_sample_pages > effective_pages) {
-+		if (effective_pages > 0) {
-+			n_sample_pages = effective_pages;
- 		} else {
- 			n_sample_pages = 1;
- 		}
-@@ -3252,9 +3522,15 @@
- 
- 	for (i = 0; i < n_sample_pages; i++) {
- 		rec_t*	supremum;
-+		ibool	is_first_page = TRUE;
- 		mtr_start(&mtr);
- 
-+		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-+			is_first_page = btr_cur_open_at_rnd_pos_after_path(index, BTR_SEARCH_LEAF,
-+									first_rec_path, &cursor, &mtr);
-+		} else {
- 		btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
-+		}
- 
- 		/* Count the number of different key values for each prefix of
- 		the key on this index page. If the prefix does not determine
-@@ -3265,7 +3541,13 @@
- 		page = btr_cur_get_page(&cursor);
- 
- 		supremum = page_get_supremum_rec(page);
-+		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS && is_first_page) {
-+			/* the cursor should be the first record of the page. */
-+			/* Counting should be started from here. */
-+			rec = btr_cur_get_rec(&cursor);
-+		} else {
- 		rec = page_rec_get_next(page_get_infimum_rec(page));
-+		}
- 
- 		if (rec != supremum) {
- 			not_empty_flag = 1;
-@@ -3274,7 +3556,8 @@
- 		}
- 
- 		while (rec != supremum) {
--			rec_t*	next_rec = page_rec_get_next(rec);
-+			rec_t*  next_rec;
-+			next_rec = page_rec_get_next(rec);
- 			if (next_rec == supremum) {
- 				break;
- 			}
-@@ -3288,7 +3571,10 @@
- 			cmp_rec_rec_with_match(rec, next_rec,
- 					       offsets_rec, offsets_next_rec,
- 					       index, &matched_fields,
--					       &matched_bytes);
-+					       &matched_bytes,
-+				(stats_method==SRV_STATS_METHOD_NULLS_NOT_EQUAL) ?
-+				SRV_STATS_METHOD_NULLS_NOT_EQUAL :
-+				SRV_STATS_METHOD_NULLS_EQUAL);
- 
- 			for (j = matched_fields + 1; j <= n_cols; j++) {
- 				/* We add one if this index record has
-@@ -3349,7 +3635,7 @@
- 	for (j = 0; j <= n_cols; j++) {
- 		index->stat_n_diff_key_vals[j]
- 			= ((n_diff[j]
--			    * (ib_int64_t)index->stat_n_leaf_pages
-+			    * (ib_int64_t)effective_pages
- 			    + n_sample_pages - 1
- 			    + total_external_size
- 			    + not_empty_flag)
-@@ -3364,7 +3650,7 @@
- 		different key values, or even more. Let us try to approximate
- 		that: */
- 
--		add_on = index->stat_n_leaf_pages
-+		add_on = effective_pages
- 			/ (10 * (n_sample_pages
- 				 + total_external_size));
- 
-@@ -3373,6 +3659,15 @@
- 		}
- 
- 		index->stat_n_diff_key_vals[j] += add_on;
-+
-+		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-+			/* index->stat_n_diff_key_vals[k] is used for calc rec_per_key,
-+			as "stats.records / index->stat_n_diff_key_vals[x]".
-+			So it should be adjusted to the value which is based on whole of the index. */
-+			index->stat_n_diff_key_vals[j] =
-+				index->stat_n_diff_key_vals[j] * (ib_int64_t)index->stat_n_leaf_pages
-+					/ (ib_int64_t)effective_pages;
-+		}
- 	}
- 
- 	mem_free(n_diff);
 diff -ruN a/storage/innodb_plugin/dict/dict0boot.c b/storage/innodb_plugin/dict/dict0boot.c
 --- a/storage/innodb_plugin/dict/dict0boot.c	2010-08-27 16:11:12.152990021 +0900
 +++ b/storage/innodb_plugin/dict/dict0boot.c	2010-08-27 16:16:49.202982244 +0900
@@ -442,22 +47,26 @@ diff -ruN a/storage/innodb_plugin/dict/dict0boot.c b/storage/innodb_plugin/dict/
  
  	index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
  				      DICT_HDR_SPACE,
-@@ -441,6 +464,41 @@
+@@ -441,6 +464,45 @@
  					FALSE);
  	ut_a(error == DB_SUCCESS);
  
 +	/*-------------------------*/
-+	table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 3, 0);
++	table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 4, 0);
 +	table->n_mysql_handles_opened = 1; /* for pin */
 +
 +	dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
 +	dict_mem_table_add_col(table, heap, "KEY_COLS", DATA_INT, 0, 4);
 +	dict_mem_table_add_col(table, heap, "DIFF_VALS", DATA_BINARY, 0, 0);
++	dict_mem_table_add_col(table, heap, "NON_NULL_VALS", DATA_BINARY, 0, 0);
 +
 +	/* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
 +#if DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2
 +#error "DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2"
 +#endif
++#if DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2
++#error "DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2"
++#endif
 +
 +	table->id = DICT_STATS_ID;
 +	dict_table_add_to_cache(table, heap);
@@ -484,7 +93,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0boot.c b/storage/innodb_plugin/dict/
  	mtr_commit(&mtr);
  	/*-------------------------*/
  
-@@ -454,6 +512,7 @@
+@@ -454,6 +516,7 @@
  	dict_load_sys_table(dict_sys->sys_columns);
  	dict_load_sys_table(dict_sys->sys_indexes);
  	dict_load_sys_table(dict_sys->sys_fields);
@@ -495,7 +104,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0boot.c b/storage/innodb_plugin/dict/
 diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c
 --- a/storage/innodb_plugin/dict/dict0crea.c	2010-08-27 16:11:12.152990021 +0900
 +++ b/storage/innodb_plugin/dict/dict0crea.c	2010-08-27 16:16:49.205982429 +0900
-@@ -508,6 +508,51 @@
+@@ -508,6 +508,56 @@
  }
  
  /*****************************************************************//**
@@ -520,7 +129,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
 +
 +	sys_stats = dict_sys->sys_stats;
 +
-+	entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
++	entry = dtuple_create(heap, 4 + DATA_N_SYS_COLS);
 +
 +	dict_table_copy_types(entry, sys_stats);
 +
@@ -539,6 +148,11 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
 +	ptr = mem_heap_alloc(heap, 8);
 +	mach_write_to_8(ptr, ut_dulint_zero); /* initial value is 0 */
 +	dfield_set_data(dfield, ptr, 8);
++	/* 5: NON_NULL_VALS ------------------*/
++	dfield = dtuple_get_nth_field(entry, 3/*NON_NULL_VALS*/);
++	ptr = mem_heap_alloc(heap, 8);
++	mach_write_to_8(ptr, ut_dulint_zero); /* initial value is 0 */
++	dfield_set_data(dfield, ptr, 8);
 +
 +	return(entry);
 +}
@@ -547,7 +161,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
  Creates the tuple with which the index entry is searched for writing the index
  tree root page number, if such a tree is created.
  @return	the tuple for search */
-@@ -617,6 +662,27 @@
+@@ -617,6 +667,27 @@
  }
  
  /***************************************************************//**
@@ -575,7 +189,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
  Creates an index tree for the index if it is not a member of a cluster.
  @return	DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
  static
-@@ -938,6 +1004,49 @@
+@@ -938,6 +1009,49 @@
  					  dict_sys->sys_fields, heap);
  	node->field_def->common.parent = node;
  
@@ -625,7 +239,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
  	node->commit_node = commit_node_create(heap);
  	node->commit_node->common.parent = node;
  
-@@ -1088,6 +1197,7 @@
+@@ -1088,6 +1202,7 @@
  
  		node->state = INDEX_BUILD_FIELD_DEF;
  		node->field_no = 0;
@@ -633,7 +247,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
  
  		thr->run_node = node->ind_def;
  
-@@ -1133,7 +1243,31 @@
+@@ -1133,7 +1248,31 @@
  			goto function_exit;
  		}
  
@@ -666,7 +280,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/
  	}
  
  	if (node->state == INDEX_CREATE_INDEX_TREE) {
-@@ -1179,6 +1313,66 @@
+@@ -1179,6 +1318,66 @@
  		return(NULL);
  	}
  
@@ -745,7 +359,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  	}
  
  	return(table);
-@@ -4276,6 +4276,255 @@
+@@ -4282,6 +4282,307 @@
  }
  
  /*********************************************************************//**
@@ -803,15 +417,18 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +	ulint		key_cols;
 +	ulint		n_cols;
 +	const rec_t*	rec;
++	ulint		n_fields;
 +	const byte*	field;
 +	ulint		len;
 +	ib_int64_t*	stat_n_diff_key_vals_tmp;
++	ib_int64_t*	stat_n_non_null_key_vals_tmp;
 +	byte*		buf;
 +	ulint		i;
 +	mtr_t		mtr;
 +
 +	n_cols = dict_index_get_n_unique(index);
 +	stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
++	stat_n_non_null_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
 +
 +	sys_stats = dict_sys->sys_stats;
 +	sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
@@ -847,9 +464,13 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +		}
 +
 +		if (rec_get_deleted_flag(rec, 0)) {
++			/* don't count */
++			i--;
 +			goto next_rec;
 +		}
 +
++		n_fields = rec_get_n_fields_old(rec);
++
 +		field = rec_get_nth_field_old(rec, 1, &len);
 +		ut_a(len == 4);
 +
@@ -861,6 +482,21 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +		ut_a(len == 8);
 +
 +		stat_n_diff_key_vals_tmp[i] = ut_conv_dulint_to_longlong(mach_read_from_8(field));
++
++		if (n_fields > DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
++			field = rec_get_nth_field_old(rec, DICT_SYS_STATS_NON_NULL_VALS_FIELD, &len);
++			ut_a(len == 8);
++
++			stat_n_non_null_key_vals_tmp[i] = ut_conv_dulint_to_longlong(mach_read_from_8(field));
++		} else {
++			/* not enough fields: should be older */
++			fprintf(stderr, "InnoDB: Notice: stats for %s/%s (%lu/%lu)"
++					" in SYS_STATS seems older format. "
++					"Please execute ANALYZE TABLE for it.\n",
++					index->table_name, index->name, i, n_cols);
++
++			stat_n_non_null_key_vals_tmp[i] = ((ib_int64_t)(-1));
++		}
 +next_rec:
 +		btr_pcur_move_to_next_user_rec(&pcur, &mtr);
 +	}
@@ -870,6 +506,12 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +
 +	for (i = 0; i <= n_cols; i++) {
 +		index->stat_n_diff_key_vals[i] = stat_n_diff_key_vals_tmp[i];
++		if (stat_n_non_null_key_vals_tmp[i] == ((ib_int64_t)(-1))) {
++			/* approximate value */
++			index->stat_n_non_null_key_vals[i] = stat_n_diff_key_vals_tmp[n_cols];
++		} else {
++			index->stat_n_non_null_key_vals[i] = stat_n_non_null_key_vals_tmp[i];
++		}
 +	}
 +}
 +/*===========================================*/
@@ -914,18 +556,22 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +	ulint		n_cols;
 +	ulint		rests;
 +	const rec_t*	rec;
++	ulint		n_fields;
 +	const byte*	field;
 +	ulint		len;
 +	ib_int64_t*	stat_n_diff_key_vals_tmp;
++	ib_int64_t*	stat_n_non_null_key_vals_tmp;
 +	byte*		buf;
 +	ulint		i;
 +	mtr_t		mtr;
 +
 +	n_cols = dict_index_get_n_unique(index);
 +	stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
++	stat_n_non_null_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
 +
 +	for (i = 0; i <= n_cols; i++) {
 +		stat_n_diff_key_vals_tmp[i] = index->stat_n_diff_key_vals[i];
++		stat_n_non_null_key_vals_tmp[i] = index->stat_n_non_null_key_vals[i];
 +	}
 +
 +	sys_stats = dict_sys->sys_stats;
@@ -959,6 +605,18 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +		}
 +
 +		if (rec_get_deleted_flag(rec, 0)) {
++			/* don't count */
++			i--;
++			goto next_rec;
++		}
++
++		n_fields = rec_get_n_fields_old(rec);
++
++		if (n_fields <= DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
++			/* not update for the older smaller format */
++			fprintf(stderr, "InnoDB: Notice: stats for %s/%s (%lu/%lu)"
++					" in SYS_STATS seems older format. Please ANALYZE TABLE it.\n",
++					index->table_name, index->name, i, n_cols);
 +			goto next_rec;
 +		}
 +
@@ -975,6 +633,14 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
 +						(ulint) stat_n_diff_key_vals_tmp[key_cols] & 0xFFFFFFFF),
 +				&mtr);
 +
++		field = rec_get_nth_field_old(rec, DICT_SYS_STATS_NON_NULL_VALS_FIELD, &len);
++		ut_a(len == 8);
++
++		mlog_write_dulint((byte*)field,
++				ut_dulint_create((ulint) (stat_n_non_null_key_vals_tmp[key_cols] >> 32),
++						(ulint) stat_n_non_null_key_vals_tmp[key_cols] & 0xFFFFFFFF),
++				&mtr);
++
 +		rests--;
 +
 +next_rec:
@@ -1001,7 +667,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  Calculates new estimates for table and index statistics. The statistics
  are used in query optimization. */
  UNIV_INTERN
-@@ -4283,10 +4532,11 @@
+@@ -4289,10 +4590,11 @@
  dict_update_statistics(
  /*===================*/
  	dict_table_t*	table,		/*!< in/out: table */
@@ -1014,7 +680,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  {
  	dict_index_t*	index;
  	ulint		sum_of_index_sizes	= 0;
-@@ -4303,6 +4553,27 @@
+@@ -4309,6 +4611,27 @@
  		return;
  	}
  
@@ -1042,7 +708,7 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  	/* Find out the sizes of the indexes and how many different values
  	for the key they approximately have */
  
-@@ -4363,6 +4634,11 @@
+@@ -4373,6 +4696,11 @@
  		index = dict_table_get_next_index(index);
  	} while (index);
  
@@ -1054,7 +720,86 @@ diff -ruN a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/
  	index = dict_table_get_first_index(table);
  
  	table->stat_n_rows = index->stat_n_diff_key_vals[
-@@ -4457,7 +4733,7 @@
+@@ -4390,6 +4718,78 @@
+ 	dict_table_stats_unlock(table, RW_X_LATCH);
+ }
+ 
++/*********************************************************************//**
++*/
++UNIV_INTERN
++ibool
++dict_is_older_statistics(
++/*=====================*/
++	dict_index_t*	index)
++{
++	mem_heap_t*	heap;
++	dict_table_t*	sys_stats;
++	dict_index_t*	sys_index;
++	btr_pcur_t	pcur;
++	dtuple_t*	tuple;
++	dfield_t*	dfield;
++	const rec_t*	rec;
++	ulint		n_fields;
++	ulint		len;
++	byte*		buf;
++	mtr_t		mtr;
++
++	heap = mem_heap_create(100);
++
++	sys_stats = dict_sys->sys_stats;
++	sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
++	ut_a(!dict_table_is_comp(sys_stats));
++
++	tuple = dtuple_create(heap, 1);
++	dfield = dtuple_get_nth_field(tuple, 0);
++
++	buf = mem_heap_alloc(heap, 8);
++	mach_write_to_8(buf, index->id);
++
++	dfield_set_data(dfield, buf, 8);
++	dict_index_copy_types(tuple, sys_index, 1);
++
++	mtr_start(&mtr);
++
++	btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
++				  BTR_SEARCH_LEAF, &pcur, &mtr);
++
++next_rec:
++	rec = btr_pcur_get_rec(&pcur);
++
++	if (!btr_pcur_is_on_user_rec(&pcur)
++	    || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
++			     index->id)) {
++		/* not found */
++		btr_pcur_close(&pcur);
++		mtr_commit(&mtr);
++		mem_heap_free(heap);
++		/* no statistics == not older statistics */
++		return(FALSE);
++	}
++
++	if (rec_get_deleted_flag(rec, 0)) {
++		btr_pcur_move_to_next_user_rec(&pcur, &mtr);
++		goto next_rec;
++	}
++
++	n_fields = rec_get_n_fields_old(rec);
++
++	btr_pcur_close(&pcur);
++	mtr_commit(&mtr);
++	mem_heap_free(heap);
++
++	if (n_fields > DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
++		return(FALSE);
++	} else {
++		return(TRUE);
++	}
++}
++
+ /**********************************************************************//**
+ Prints info of a foreign key constraint. */
+ static
+@@ -4467,7 +4867,7 @@
  
  	ut_ad(mutex_own(&(dict_sys->mutex)));
  
@@ -1086,7 +831,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  static char*	internal_innobase_data_file_path	= NULL;
  
-@@ -2211,6 +2212,8 @@
+@@ -2230,6 +2231,8 @@
  
  	srv_extra_undoslots = (ibool) innobase_extra_undoslots;
  
@@ -1095,7 +840,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* -------------- Log files ---------------------------*/
  
  	/* The default dir for log files is the datadir of MySQL */
-@@ -4981,6 +4984,10 @@
+@@ -5000,6 +5003,10 @@
  
  	error = row_insert_for_mysql((byte*) record, prebuilt);
  
@@ -1106,7 +851,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	/* Handle duplicate key errors */
  	if (auto_inc_used) {
  		ulint		err;
-@@ -5317,6 +5324,10 @@
+@@ -5336,6 +5343,10 @@
  		}
  	}
  
@@ -1117,7 +862,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	innodb_srv_conc_exit_innodb(trx);
  
  	error = convert_error_code_to_mysql(error,
-@@ -5370,6 +5381,10 @@
+@@ -5389,6 +5400,10 @@
  
  	error = row_update_for_mysql((byte*) record, prebuilt);
  
@@ -1128,7 +873,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  	innodb_srv_conc_exit_innodb(trx);
  
  	error = convert_error_code_to_mysql(
-@@ -5688,6 +5703,11 @@
+@@ -5707,6 +5722,11 @@
  	case DB_SUCCESS:
  		error = 0;
  		table->status = 0;
@@ -1140,7 +885,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		break;
  	case DB_RECORD_NOT_FOUND:
  		error = HA_ERR_KEY_NOT_FOUND;
-@@ -5897,6 +5917,11 @@
+@@ -5916,6 +5936,11 @@
  	case DB_SUCCESS:
  		error = 0;
  		table->status = 0;
@@ -1152,7 +897,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  		break;
  	case DB_RECORD_NOT_FOUND:
  		error = HA_ERR_END_OF_FILE;
-@@ -7791,11 +7816,31 @@
+@@ -7869,11 +7894,35 @@
  			/* In sql_show we call with this flag: update
  			then statistics so that they are up-to-date */
  
@@ -1169,6 +914,10 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
 +				for (index = dict_table_get_first_index(ib_table);
 +				     index != NULL;
 +				     index = dict_table_get_next_index(index)) {
++					if (dict_is_older_statistics(index)) {
++						row_delete_stats_for_mysql(index, prebuilt->trx);
++						innobase_commit_low(prebuilt->trx);
++					}
 +					row_insert_stats_for_mysql(index, prebuilt->trx);
 +					innobase_commit_low(prebuilt->trx);
 +				}
@@ -1185,7 +934,7 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  
  			prebuilt->trx->op_info = "returning various info to MySQL";
  		}
-@@ -7873,7 +7918,7 @@
+@@ -7951,7 +8000,7 @@
  		are asked by MySQL to avoid locking. Another reason to
  		avoid the call is that it uses quite a lot of CPU.
  		See Bug#38185. */
@@ -1194,29 +943,10 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  			/* We do not update delete_length if no
  			locking is requested so the "old" value can
  			remain. delete_length is initialized to 0 in
-@@ -11053,6 +11098,45 @@
+@@ -11126,6 +11175,26 @@
    "The number of index pages to sample when calculating statistics (default 8)",
    NULL, NULL, 8, 1, ~0ULL, 0);
  
-+const char *innobase_stats_method_names[]=
-+{
-+  "nulls_equal",
-+  "nulls_unequal",
-+  "nulls_ignored",
-+  NullS
-+};
-+TYPELIB innobase_stats_method_typelib=
-+{
-+  array_elements(innobase_stats_method_names) - 1, "innobase_stats_method_typelib",
-+  innobase_stats_method_names, NULL
-+};
-+static MYSQL_SYSVAR_ENUM(stats_method, srv_stats_method,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Specifies how InnoDB index statistics collection code should threat NULLs. "
-+  "Possible values of name are same to for 'myisam_stats_method'. "
-+  "This is startup parameter.",
-+  NULL, NULL, 0, &innobase_stats_method_typelib);
-+
 +static MYSQL_SYSVAR_ULONG(stats_auto_update, srv_stats_auto_update,
 +  PLUGIN_VAR_RQCMDARG,
 +  "Enable/Disable InnoDB's auto update statistics of indexes. "
@@ -1240,18 +970,17 @@ diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/h
  static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
    PLUGIN_VAR_OPCMDARG,
    "Enable InnoDB adaptive hash index (enabled by default).  "
-@@ -11371,6 +11455,10 @@
+@@ -11451,6 +11520,9 @@
    MYSQL_SYSVAR(overwrite_relay_log_info),
    MYSQL_SYSVAR(rollback_on_timeout),
    MYSQL_SYSVAR(stats_on_metadata),
-+  MYSQL_SYSVAR(stats_method),
 +  MYSQL_SYSVAR(stats_auto_update),
 +  MYSQL_SYSVAR(stats_update_need_lock),
 +  MYSQL_SYSVAR(use_sys_stats_table),
    MYSQL_SYSVAR(stats_sample_pages),
    MYSQL_SYSVAR(adaptive_hash_index),
<Skipped 1467 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/percona-server.git/commitdiff/bf636d07b36bfd2921b9ecf2033c78270355c98c



More information about the pld-cvs-commit mailing list