[packages/percona-server/v5.1.x: 5/21] - add percona patches (release-5.1.53-11)

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


commit 8c0fcd576584cf0397e2b088fb33bc07c1813ba8
Author: Elan Ruusamäe <glen at pld-linux.org>
Date:   Fri Dec 17 11:41:48 2010 +0000

    - add percona patches (release-5.1.53-11)
    
    Changed files:
        mysql-bug580324.patch -> 1.1.2.1
        mysql-bug677407.patch -> 1.1.2.1
        mysql-error_pad.patch -> 1.1.2.1
        mysql-i_s_innodb_buffer_pool_pages.patch -> 1.1.2.1
        mysql-innodb_adjust_defaults.patch -> 1.1.2.1
        mysql-innodb_admin_command_base.patch -> 1.1.2.1
        mysql-innodb_deadlock_count.patch -> 1.1.2.1
        mysql-innodb_expand_import.patch -> 1.1.2.1
        mysql-innodb_expand_undo_slots.patch -> 1.1.2.1
        mysql-innodb_fast_checksum.patch -> 1.1.2.1
        mysql-innodb_files_extend.patch -> 1.1.2.1
        mysql-innodb_fix_misc.patch -> 1.1.2.1
        mysql-innodb_lru_dump_restore.patch -> 1.1.2.1
        mysql-innodb_opt_lru_count.patch -> 1.1.2.1
        mysql-innodb_overwrite_relay_log_info.patch -> 1.1.2.1
        mysql-innodb_pass_corrupt_table.patch -> 1.1.2.1
        mysql-innodb_purge_thread.patch -> 1.1.2.1
        mysql-innodb_separate_doublewrite.patch -> 1.1.2.1
        mysql-innodb_show_enhancements.patch -> 1.1.2.1
        mysql-innodb_show_lock_name.patch -> 1.1.2.1
        mysql-innodb_show_status.patch -> 1.1.2.1
        mysql-innodb_show_sys_tables.patch -> 1.1.2.1
        mysql-innodb_stats.patch -> 1.1.2.1
        mysql-innodb_swap_builtin_plugin.patch -> 1.1.2.1
        mysql-mysql_dump_ignore_ct.patch -> 1.1.2.1
        mysql-optimizer_fix.patch -> 1.1.2.1
        mysql-query_cache_enhance.patch -> 1.1.2.1
        mysql-show_temp_51.patch -> 1.1.2.1
        mysql-slow_extended.patch -> 1.1.2.1
        mysql-suppress_log_warning_1592.patch -> 1.1.2.1

 mysql-bug580324.patch                       |  105 ++
 mysql-bug677407.patch                       |  138 ++
 mysql-error_pad.patch                       |  267 ++++
 mysql-i_s_innodb_buffer_pool_pages.patch    |  797 ++++++++++
 mysql-innodb_adjust_defaults.patch          |   48 +
 mysql-innodb_admin_command_base.patch       |  181 +++
 mysql-innodb_deadlock_count.patch           |   73 +
 mysql-innodb_expand_import.patch            |  555 +++++++
 mysql-innodb_expand_undo_slots.patch        |  150 ++
 mysql-innodb_fast_checksum.patch            |  311 ++++
 mysql-innodb_files_extend.patch             |  422 ++++++
 mysql-innodb_fix_misc.patch                 |  137 ++
 mysql-innodb_lru_dump_restore.patch         |  698 +++++++++
 mysql-innodb_opt_lru_count.patch            |  313 ++++
 mysql-innodb_overwrite_relay_log_info.patch |  499 +++++++
 mysql-innodb_pass_corrupt_table.patch       | 1370 +++++++++++++++++
 mysql-innodb_purge_thread.patch             |  522 +++++++
 mysql-innodb_separate_doublewrite.patch     |  963 ++++++++++++
 mysql-innodb_show_enhancements.patch        |  275 ++++
 mysql-innodb_show_lock_name.patch           |  338 +++++
 mysql-innodb_show_status.patch              |  456 ++++++
 mysql-innodb_show_sys_tables.patch          |  718 +++++++++
 mysql-innodb_stats.patch                    | 2135 +++++++++++++++++++++++++++
 mysql-innodb_swap_builtin_plugin.patch      |  163 ++
 mysql-mysql_dump_ignore_ct.patch            |   62 +
 mysql-optimizer_fix.patch                   |  174 +++
 mysql-query_cache_enhance.patch             |  892 +++++++++++
 mysql-show_temp_51.patch                    |  393 +++++
 mysql-slow_extended.patch                   | 1474 ++++++++++++++++++
 mysql-suppress_log_warning_1592.patch       |   71 +
 30 files changed, 14700 insertions(+)
---
diff --git a/mysql-bug580324.patch b/mysql-bug580324.patch
new file mode 100644
index 0000000..3947fde
--- /dev/null
+++ b/mysql-bug580324.patch
@@ -0,0 +1,105 @@
+# name       : bug580324.patch
+# introduced : 11 or before
+# maintainer : Oleg
+#
+#!!! notice !!!
+# Any small change to this file in the main branch
+# should be done or reviewed by the maintainer!
+diff -ruN a/sql/sql_base.cc b/sql/sql_base.cc
+--- a/sql/sql_base.cc	2010-05-27 19:54:18.000000000 +0400
++++ b/sql/sql_base.cc	2010-05-27 19:55:20.000000000 +0400
+@@ -233,8 +233,12 @@
+ uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
+                           bool tmp_table)
+ {
+-  uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
+-                                  table_list->table_name)-key)+1;
++  char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
++  *db_end++= '\0';
++  char *table_end= strnmov(db_end, table_list->table_name,
++                           key + MAX_DBKEY_LENGTH - 1 - db_end);
++  *table_end++= '\0';
++  uint key_length= (uint) (table_end-key);
+   if (tmp_table)
+   {
+     int4store(key + key_length, thd->server_id);
+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 @@
+     break;
+ #else
+   {
+-    char *fields, *packet_end= packet + packet_length, *arg_end;
++    char *fields, *packet_end= packet + packet_length, *wildcard;
+     /* Locked closure of all tables */
+     TABLE_LIST table_list;
+-    LEX_STRING conv_name;
++    char db_buff[NAME_LEN+1];
++    uint32 db_length;
++    uint dummy_errors;
+ 
+     /* used as fields initializator */
+     lex_start(thd);
+@@ -1342,26 +1344,22 @@
+     /*
+       We have name + wildcard in packet, separated by endzero
+     */
+-    arg_end= strend(packet);
+-    uint arg_length= arg_end - packet;
+-    
+-    /* Check given table name length. */
+-    if (arg_length >= packet_length || arg_length > NAME_LEN)
++    wildcard= strend(packet);
++    db_length= wildcard - packet;
++    wildcard++;
++    uint query_length= (uint) (packet_end - wildcard); // Don't count end \0
++    if (db_length > NAME_LEN || query_length > NAME_LEN)
+     {
+       my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+       break;
+     }
+-    thd->convert_string(&conv_name, system_charset_info,
+-			packet, arg_length, thd->charset());
+-    if (check_table_name(conv_name.str, conv_name.length, FALSE))
+-    {
+-      /* this is OK due to convert_string() null-terminating the string */
+-      my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
++    db_length= copy_and_convert(db_buff, sizeof(db_buff)-1,
++                                system_charset_info, packet, db_length,
++                                thd->charset(), &dummy_errors);
++    db_buff[db_length]= '\0';
++    table_list.alias= table_list.table_name= db_buff;
++    if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
+       break;
+-    }
+-
+-    table_list.alias= table_list.table_name= conv_name.str;
+-    packet= arg_end + 1;
+ 
+     if (is_schema_db(table_list.db, table_list.db_length))
+     {
+@@ -1370,9 +1368,6 @@
+         table_list.schema_table= schema_table;
+     }
+ 
+-    uint query_length= (uint) (packet_end - packet); // Don't count end \0
+-    if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
+-      break;
+     thd->set_query(fields, query_length);
+     general_log_print(thd, command, "%s %s", table_list.table_name, fields);
+     if (lower_case_table_names)
+diff -ruN a/strings/ctype-utf8.c b/strings/ctype-utf8.c
+--- a/strings/ctype-utf8.c	2010-05-06 19:28:05.000000000 +0400
++++ b/strings/ctype-utf8.c	2010-05-27 20:04:20.000000000 +0400
+@@ -4116,6 +4116,10 @@
+ {
+   int code;
+   char hex[]= "0123456789abcdef";
++
++  if (s >= e)
++    return MY_CS_TOOSMALL;
++
+   if (wc < 128 && filename_safe_char[wc])
+   {
+     *s= (uchar) wc;
diff --git a/mysql-bug677407.patch b/mysql-bug677407.patch
new file mode 100644
index 0000000..873a6a1
--- /dev/null
+++ b/mysql-bug677407.patch
@@ -0,0 +1,138 @@
+# name       : bug677407
+# introduced : 13
+# maintainer : Alexey
+
+LP bug#677407 / MySQL Bug#48883: Stale data from INNODB_LOCKS table.
+
+The innodb.innodb_information_schema test could fail sporadically due to
+the flawed logic in the INFORMATION_SCHEMA.INNODB_LOCKS caching
+mechanism.
+
+The logic for how to check when to update the table cache for
+INNODB_LOCKS with real data was flawed. This could result in both not
+updating the cache often enough (when the table is queried repeatedly
+with less than 100 milliseconds in-between) resulting in stale data; as
+well as updating too often (when multiple queries against the table
+start at around the same time).
+
+Fixed by updating the "last updated" timestamp in the right place, when
+the cache is updated, not when it is read.
+
+I hereby grant Percona the following BSD license to this patch for
+inclusion in Percona Server:
+
+Copyright (c) 2010, Kristian Nielsen All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of the author nor the names of its contributors
+      may be used to endorse or promote products derived from this
+      software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--- a/storage/innodb_plugin/trx/trx0i_s.c	2010-11-03 16:39:54.000000000 +0300
++++ b/storage/innodb_plugin/trx/trx0i_s.c	2010-11-30 13:57:03.000000000 +0300
+@@ -157,10 +157,6 @@
+ 	ullint		last_read;	/*!< last time the cache was read;
+ 					measured in microseconds since
+ 					epoch */
+-	mutex_t		last_read_mutex;/*!< mutex protecting the
+-					last_read member - it is updated
+-					inside a shared lock of the
+-					rw_lock member */
+ 	i_s_table_cache_t innodb_trx;	/*!< innodb_trx table */
+ 	i_s_table_cache_t innodb_locks;	/*!< innodb_locks table */
+ 	i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
+@@ -1101,13 +1097,6 @@
+ {
+ 	ullint	now;
+ 
+-	/* Here we read cache->last_read without acquiring its mutex
+-	because last_read is only updated when a shared rw lock on the
+-	whole cache is being held (see trx_i_s_cache_end_read()) and
+-	we are currently holding an exclusive rw lock on the cache.
+-	So it is not possible for last_read to be updated while we are
+-	reading it. */
+-
+ #ifdef UNIV_SYNC_DEBUG
+ 	ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
+ #endif
+@@ -1205,6 +1194,12 @@
+ /*===================================*/
+ 	trx_i_s_cache_t*	cache)	/*!< in/out: cache */
+ {
++	ullint	now;
++
++#ifdef UNIV_SYNC_DEBUG
++	ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
++#endif
++
+ 	if (!can_cache_be_updated(cache)) {
+ 
+ 		return(1);
+@@ -1217,6 +1212,10 @@
+ 
+ 	mutex_exit(&kernel_mutex);
+ 
++	/* update cache last read time */
++	now = ut_time_us(NULL);
++	cache->last_read = now;
++
+ 	return(0);
+ }
+ 
+@@ -1247,16 +1246,12 @@
+ 	release kernel_mutex
+ 	release trx_i_s_cache_t::rw_lock
+ 	acquire trx_i_s_cache_t::rw_lock, S
+-	acquire trx_i_s_cache_t::last_read_mutex
+-	release trx_i_s_cache_t::last_read_mutex
+ 	release trx_i_s_cache_t::rw_lock */
+ 
+ 	rw_lock_create(&cache->rw_lock, SYNC_TRX_I_S_RWLOCK);
+ 
+ 	cache->last_read = 0;
+ 
+-	mutex_create(&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ);
+-
+ 	table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t));
+ 	table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t));
+ 	table_cache_init(&cache->innodb_lock_waits,
+@@ -1307,18 +1302,10 @@
+ /*===================*/
+ 	trx_i_s_cache_t*	cache)	/*!< in: cache */
+ {
+-	ullint	now;
+-
+ #ifdef UNIV_SYNC_DEBUG
+ 	ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED));
+ #endif
+ 
+-	/* update cache last read time */
+-	now = ut_time_us(NULL);
+-	mutex_enter(&cache->last_read_mutex);
+-	cache->last_read = now;
+-	mutex_exit(&cache->last_read_mutex);
+-
+ 	rw_lock_s_unlock(&cache->rw_lock);
+ }
+ 
diff --git a/mysql-error_pad.patch b/mysql-error_pad.patch
new file mode 100644
index 0000000..fa452c7
--- /dev/null
+++ b/mysql-error_pad.patch
@@ -0,0 +1,267 @@
+# name       : error_pad.patch
+# introduced : 12
+# maintainer : Oleg
+#
+#!!! notice !!!
+# Any small change to this file in the main branch
+# should be done or reviewed by the maintainer!
+diff -ruN a/extra/comp_err.c b/extra/comp_err.c
+--- a/extra/comp_err.c	2010-08-03 17:24:24.000000000 +0000
++++ b/extra/comp_err.c	2010-09-14 16:49:28.000000000 +0000
+@@ -30,11 +30,12 @@
+ #include <assert.h>
+ #include <my_dir.h>
+ 
+-#define MAX_ROWS  1000
++#define MAX_ROWS  5000
+ #define HEADER_LENGTH 32                /* Length of header in errmsg.sys */
+ #define DEFAULT_CHARSET_DIR "../sql/share/charsets"
+ #define ER_PREFIX "ER_"
+ #define WARN_PREFIX "WARN_"
++#define PADD_PREFIX "PADD_"
+ static char *OUTFILE= (char*) "errmsg.sys";
+ static char *HEADERFILE= (char*) "mysqld_error.h";
+ static char *NAMEFILE= (char*) "mysqld_ername.h";
+@@ -89,6 +90,7 @@
+   const char *sql_code1;		/* sql state */
+   const char *sql_code2;		/* ODBC state */
+   struct errors *next_error;            /* Pointer to next error */
++  my_bool is_padding;                   /* If true - padd this er_name while er_code != d_code*/
+   DYNAMIC_ARRAY msg;                    /* All language texts for this error */
+ };
+ 
+@@ -127,6 +129,7 @@
+ 
+ 
+ static struct languages *parse_charset_string(char *str);
++static struct errors *parse_padd_string(char *ptr, int er_count);
+ static struct errors *parse_error_string(char *ptr, int er_count);
+ static struct message *parse_message_string(struct message *new_message,
+ 					    char *str);
+@@ -229,6 +232,11 @@
+ 
+   for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
+   {
++    if (tmp_error->is_padding)
++    {
++      er_last= tmp_error->d_code;
++      continue;
++    }
+     /*
+        generating mysqld_error.h
+        fprintf() will automatically add \r on windows
+@@ -318,12 +326,29 @@
+ 		"language\n", tmp_error->er_name, tmp_lang->lang_short_name);
+ 	goto err;
+       }
+-      if (copy_rows(to, tmp->text, row_nr, start_pos))
++      if (tmp_error->is_padding)
+       {
+-	fprintf(stderr, "Failed to copy rows to %s\n", outfile);
+-	goto err;
++        int padd_to= tmp_error->d_code;
++        char* padd_message= tmp->text;
++        while ((row_nr+er_offset) < padd_to)
++        {
++          if (copy_rows(to, padd_message,row_nr,start_pos))
++          {
++            fprintf(stderr, "Failed to copy rows to %s\n", outfile);
++            goto err;
++          }
++          row_nr++;
++        }
++      }
++      else
++      {
++        if (copy_rows(to, tmp->text, row_nr, start_pos))
++        {
++          fprintf(stderr, "Failed to copy rows to %s\n", outfile);
++          goto err;
++        }
++        row_nr++;
+       }
+-      row_nr++;
+     }
+ 
+     /* continue with header of the errmsg.sys file */
+@@ -474,14 +499,26 @@
+ 	DBUG_RETURN(0);
+       continue;
+     }
+-    if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX))
++    if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX) || is_prefix(str, PADD_PREFIX))
+     {
+-      if (!(current_error= parse_error_string(str, rcount)))
++      if (is_prefix(str, PADD_PREFIX))
+       {
+-	fprintf(stderr, "Failed to parse the error name string\n");
+-	DBUG_RETURN(0);
++        if (!(current_error= parse_padd_string(str, rcount)))
++        {
++          fprintf(stderr, "Failed to parse the error padd string\n");
++          DBUG_RETURN(0);
++        }
++        rcount= current_error->d_code - er_offset;  /* Count number of unique errors */
++      }
++      else
++      {
++        if (!(current_error= parse_error_string(str, rcount)))
++        {
++          fprintf(stderr, "Failed to parse the error name string\n");
++          DBUG_RETURN(0);
++        }
++        rcount++;                         /* Count number of unique errors */
+       }
+-      rcount++;                         /* Count number of unique errors */
+ 
+       /* add error to the list */
+       *tail_error= current_error;
+@@ -822,78 +859,122 @@
+   DBUG_RETURN(new_message);
+ }
+ 
++static struct errors* create_new_error(my_bool is_padding, char *er_name, int d_code, const char *sql_code1, const char *sql_code2)
++{
++  struct errors *new_error;
++  DBUG_ENTER("create_new_error");
++  /* create a new element */
++  new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
++  if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
++    DBUG_RETURN(0);				/* OOM: Fatal error */
++  new_error->is_padding= is_padding;
++  DBUG_PRINT("info", ("is_padding: %s", (is_padding ? "true" : "false")));
++  new_error->er_name= er_name;
++  DBUG_PRINT("info", ("er_name: %s", er_name));
++  new_error->d_code= d_code;
++  DBUG_PRINT("info", ("d_code: %d", d_code));
++  new_error->sql_code1= sql_code1;
++  DBUG_PRINT("info", ("sql_code1: %s", sql_code1));
++  new_error->sql_code2= sql_code2;
++  DBUG_PRINT("info", ("sql_code2: %s", sql_code2));
++  DBUG_RETURN(new_error);
++}
+ 
+ /*
+-  Parsing the string with error name and codes; returns the pointer to
++  Parsing the string with padd syntax (name + error to pad); returns the pointer to
+   the errors struct
+ */
+ 
+-static struct errors *parse_error_string(char *str, int er_count)
++static struct errors *parse_padd_string(char* str, int er_count)
+ {
+-  struct errors *new_error;
++  char *er_name;
++  uint d_code;
++  char *start;
+   DBUG_ENTER("parse_error_string");
+   DBUG_PRINT("enter", ("str: %s", str));
+ 
+-  /* create a new element */
+-  new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
++  start= str;
++  str= skip_delimiters(str);
+ 
+-  if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
++  /* getting the error name */
++
++  if (!(er_name= get_word(&str)))
+     DBUG_RETURN(0);				/* OOM: Fatal error */
+ 
+-  /* getting the error name */
+   str= skip_delimiters(str);
+ 
+-  if (!(new_error->er_name= get_word(&str)))
++  if (!(d_code= parse_error_offset(start)))
++  {
++    fprintf(stderr, "Failed to parse the error padd string '%s' '%s' (d_code doesn't parse)!\n",er_name,str);
++    DBUG_RETURN(0);
++  }
++  if (d_code < (er_offset + er_count))
++  {
++    fprintf(stderr, "Error to padding less current error number!\n");
++    DBUG_RETURN(0);
++  }
++  DBUG_RETURN(create_new_error(TRUE,er_name,d_code,empty_string,empty_string));
++}
++
++/*
++  Parsing the string with error name and codes; returns the pointer to
++  the errors struct
++*/
++
++static struct errors *parse_error_string(char *str, int er_count)
++{
++  char *er_name;
++  int d_code;
++  const char *sql_code1= empty_string;
++  const char *sql_code2= empty_string;
++  DBUG_ENTER("parse_error_string");
++  DBUG_PRINT("enter", ("str: %s", str));
++
++  str= skip_delimiters(str);
++
++  /* getting the error name */
++
++  if (!(er_name= get_word(&str)))
+     DBUG_RETURN(0);				/* OOM: Fatal error */
+-  DBUG_PRINT("info", ("er_name: %s", new_error->er_name));
+ 
+   str= skip_delimiters(str);
+ 
+   /* getting the code1 */
+-
+-  new_error->d_code= er_offset + er_count;
+-  DBUG_PRINT("info", ("d_code: %d", new_error->d_code));
++  d_code= er_offset + er_count;
+ 
+   str= skip_delimiters(str);
+ 
+   /* if we reached EOL => no more codes, but this can happen */
+   if (!*str)
+   {
+-    new_error->sql_code1= empty_string;
+-    new_error->sql_code2= empty_string;
+     DBUG_PRINT("info", ("str: %s", str));
+-    DBUG_RETURN(new_error);
++    goto complete_create;
+   }
+-
+   /* getting the sql_code 1 */
+-
+-  if (!(new_error->sql_code1= get_word(&str)))
++  if (!(sql_code1= get_word(&str)))
+     DBUG_RETURN(0);				/* OOM: Fatal error */
+-  DBUG_PRINT("info", ("sql_code1: %s", new_error->sql_code1));
+ 
+   str= skip_delimiters(str);
+ 
+   /* if we reached EOL => no more codes, but this can happen */
+   if (!*str)
+   {
+-    new_error->sql_code2= empty_string;
+     DBUG_PRINT("info", ("str: %s", str));
+-    DBUG_RETURN(new_error);
++    goto complete_create;
+   }
+-
+   /* getting the sql_code 2 */
+-  if (!(new_error->sql_code2= get_word(&str)))
++  if (!(sql_code2= get_word(&str)))
+     DBUG_RETURN(0);				/* OOM: Fatal error */
+-  DBUG_PRINT("info", ("sql_code2: %s", new_error->sql_code2));
+ 
+   str= skip_delimiters(str);
++
+   if (*str)
+   {
+     fprintf(stderr, "The error line did not end with sql/odbc code!");
+     DBUG_RETURN(0);
+   }
+-
+-  DBUG_RETURN(new_error);
++complete_create:
++  DBUG_RETURN(create_new_error(FALSE,er_name,d_code,sql_code1,sql_code2));
+ }
+ 
+ 
diff --git a/mysql-i_s_innodb_buffer_pool_pages.patch b/mysql-i_s_innodb_buffer_pool_pages.patch
new file mode 100644
index 0000000..1adf1b5
--- /dev/null
+++ b/mysql-i_s_innodb_buffer_pool_pages.patch
@@ -0,0 +1,797 @@
+# name       : i_s_innodb_buffer_pool_pages.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
+--- a/storage/innodb_plugin/buf/buf0buf.c	2010-07-14 15:57:23.322321253 +0900
++++ b/storage/innodb_plugin/buf/buf0buf.c	2010-07-14 16:04:45.521321527 +0900
+@@ -269,14 +269,6 @@
+ UNIV_INTERN ibool		buf_debug_prints = FALSE;
+ #endif /* UNIV_DEBUG */
+ 
+-/** A chunk of buffers.  The buffer pool is allocated in chunks. */
+-struct buf_chunk_struct{
+-	ulint		mem_size;	/*!< allocated size of the chunk */
+-	ulint		size;		/*!< size of frames[] and blocks[] */
+-	void*		mem;		/*!< pointer to the memory area which
+-					was allocated for the frames */
+-	buf_block_t*	blocks;		/*!< array of buffer control blocks */
+-};
+ #endif /* !UNIV_HOTBACKUP */
+ 
+ /********************************************************************//**
+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
+@@ -11173,6 +11173,9 @@
+   innobase_system_variables, /* system variables */
+   NULL /* reserved */
+ },
++i_s_innodb_buffer_pool_pages,
++i_s_innodb_buffer_pool_pages_index,
++i_s_innodb_buffer_pool_pages_blob,
+ i_s_innodb_trx,
+ i_s_innodb_locks,
+ i_s_innodb_lock_waits,
+diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
+--- a/storage/innodb_plugin/handler/i_s.cc	2010-04-29 15:28:20.000000000 +0900
++++ b/storage/innodb_plugin/handler/i_s.cc	2010-04-29 16:04:05.000000000 +0900
+@@ -42,6 +42,7 @@
+ #include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
+ #include "ha_prototypes.h" /* for innobase_convert_name() */
+ #include "srv0start.h" /* for srv_was_started */
++#include "btr0btr.h" /* for btr_page_get_index_id */
+ }
+ 
+ static const char plugin_author[] = "Innobase Oy";
+@@ -380,6 +381,705 @@
+ };
+ 
+ 
++static ST_FIELD_INFO	i_s_innodb_buffer_pool_pages_fields_info[] =
++{
++	{STRUCT_FLD(field_name,		"page_type"),
++	 STRUCT_FLD(field_length,	64),
++	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
++	 STRUCT_FLD(value,		0),
++	 STRUCT_FLD(field_flags,	MY_I_S_MAYBE_NULL),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"space_id"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"page_no"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"lru_position"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"fix_count"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"flush_type"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	END_OF_ST_FIELD_INFO
++};
++
++static ST_FIELD_INFO	i_s_innodb_buffer_pool_pages_index_fields_info[] =
++{
++	{STRUCT_FLD(field_name,		"index_id"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"space_id"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"page_no"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"n_recs"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"data_size"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"hashed"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"access_time"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"modified"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"dirty"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"old"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"lru_position"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"fix_count"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"flush_type"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	END_OF_ST_FIELD_INFO
++};
++
++static ST_FIELD_INFO	i_s_innodb_buffer_pool_pages_blob_fields_info[] =
++{
++	{STRUCT_FLD(field_name,		"space_id"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"page_no"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"compressed"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"part_len"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"next_page_no"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"lru_position"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"fix_count"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	{STRUCT_FLD(field_name,		"flush_type"),
++	 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),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	END_OF_ST_FIELD_INFO
++};
++
++/***********************************************************************
++Fill the dynamic table information_schema.innodb_buffer_pool_pages. */
++static
++int
++i_s_innodb_buffer_pool_pages_fill(
++/*================*/
++				/* out: 0 on success, 1 on failure */
++	THD*		thd,	/* in: thread */
++	TABLE_LIST*	tables,	/* in/out: tables to fill */
++	COND*		cond)	/* in: condition (ignored) */
++{
++	TABLE*	table	= (TABLE *) tables->table;
++	int	status	= 0;
++
++  ulint		n_chunks, n_blocks;
++
++	buf_chunk_t*	chunk;
++
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_fill");
++
++	/* deny access to non-superusers */
++	if (check_global_access(thd, PROCESS_ACL)) {
++
++		DBUG_RETURN(0);
++	}
++
++	RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
++
++	buf_pool_mutex_enter();
++	
++	chunk = buf_pool->chunks;
++  
++	for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
++		buf_block_t*	block		= chunk->blocks;
++
++    for (n_blocks	= chunk->size; n_blocks--; block++) {
++      const buf_frame_t* frame = block->frame;
++  
++      char page_type[64];
++
++      switch(fil_page_get_type(frame))
++      {
++      case FIL_PAGE_INDEX:
++        strcpy(page_type, "index");
++        break;
++      case FIL_PAGE_UNDO_LOG:
++        strcpy(page_type, "undo_log");
++        break;
++      case FIL_PAGE_INODE:
++        strcpy(page_type, "inode");
++        break;
++      case FIL_PAGE_IBUF_FREE_LIST:
++        strcpy(page_type, "ibuf_free_list");
++        break;
++      case FIL_PAGE_TYPE_ALLOCATED:
++        strcpy(page_type, "allocated");
++        break;
++      case FIL_PAGE_IBUF_BITMAP:
++        strcpy(page_type, "bitmap");
++        break;
++      case FIL_PAGE_TYPE_SYS:
++        strcpy(page_type, "sys");
++        break;
++      case FIL_PAGE_TYPE_TRX_SYS:
++        strcpy(page_type, "trx_sys");
++        break;
++      case FIL_PAGE_TYPE_FSP_HDR:
++        strcpy(page_type, "fsp_hdr");
++        break;
++      case FIL_PAGE_TYPE_XDES:
++        strcpy(page_type, "xdes");
++        break;
++      case FIL_PAGE_TYPE_BLOB:
++        strcpy(page_type, "blob");
++        break;
++      case FIL_PAGE_TYPE_ZBLOB:
++        strcpy(page_type, "zblob");
++        break;
++      case FIL_PAGE_TYPE_ZBLOB2:
++        strcpy(page_type, "zblob2");
++        break;
++      default:
++        sprintf(page_type, "unknown (type=%li)", fil_page_get_type(frame));
++      }
++      
++      field_store_string(table->field[0], page_type);
++      table->field[1]->store(block->page.space);
++      table->field[2]->store(block->page.offset);
++      table->field[3]->store(0);
++      table->field[4]->store(block->page.buf_fix_count);
++      table->field[5]->store(block->page.flush_type);
++
++      if (schema_table_store_record(thd, table)) {
++        status = 1;
++        break;
++      }
++      
++    }      
++	}
++
++	buf_pool_mutex_exit();
++
++	DBUG_RETURN(status);
++}
++
++/***********************************************************************
++Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
++static
++int
++i_s_innodb_buffer_pool_pages_index_fill(
++/*================*/
++				/* out: 0 on success, 1 on failure */
++	THD*		thd,	/* in: thread */
++	TABLE_LIST*	tables,	/* in/out: tables to fill */
++	COND*		cond)	/* in: condition (ignored) */
++{
++	TABLE*	table	= (TABLE *) tables->table;
++	int	status	= 0;
++
++  ulint		n_chunks, n_blocks;
++  dulint		index_id;
++
++	buf_chunk_t*	chunk;
++
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_fill");
++
++	/* deny access to non-superusers */
++	if (check_global_access(thd, PROCESS_ACL)) {
++
++		DBUG_RETURN(0);
++	}
++
++	RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
++
++	buf_pool_mutex_enter();
++	
++	chunk = buf_pool->chunks;
++  
++	for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
++		buf_block_t*	block		= chunk->blocks;
++
++		for (n_blocks	= chunk->size; n_blocks--; block++) {
++			const buf_frame_t* frame = block->frame;
++  
++      if (fil_page_get_type(frame) == FIL_PAGE_INDEX) {
++        index_id = btr_page_get_index_id(frame);
++        table->field[0]->store(ut_conv_dulint_to_longlong(index_id));
++        table->field[1]->store(block->page.space);
++        table->field[2]->store(block->page.offset);
++        table->field[3]->store(page_get_n_recs(frame));
++        table->field[4]->store(page_get_data_size(frame));
++        table->field[5]->store(block->is_hashed);
++        table->field[6]->store(block->page.access_time);
++        table->field[7]->store(block->page.newest_modification != 0);
++        table->field[8]->store(block->page.oldest_modification != 0);
++        table->field[9]->store(block->page.old);
++        table->field[10]->store(0);
++        table->field[11]->store(block->page.buf_fix_count);
++        table->field[12]->store(block->page.flush_type);
++          
++        if (schema_table_store_record(thd, table)) {
++          status = 1;
++          break;
++        }
++      }      
++    }
++	}
++
++	buf_pool_mutex_exit();
++
++	DBUG_RETURN(status);
++}
++
++/***********************************************************************
++Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
++static
++int
++i_s_innodb_buffer_pool_pages_blob_fill(
++/*================*/
++				/* out: 0 on success, 1 on failure */
++	THD*		thd,	/* in: thread */
++	TABLE_LIST*	tables,	/* in/out: tables to fill */
++	COND*		cond)	/* in: condition (ignored) */
++{
++	TABLE*	table	= (TABLE *) tables->table;
++	int	status	= 0;
++
++  ulint		n_chunks, n_blocks;
++	buf_chunk_t*	chunk;
++	page_zip_des_t*	block_page_zip;
++
++	ulint		part_len;
++	ulint		next_page_no;
++
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_fill");
++
++	/* deny access to non-superusers */
++	if (check_global_access(thd, PROCESS_ACL)) {
++
++		DBUG_RETURN(0);
++	}
++
++	RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
++
++	buf_pool_mutex_enter();
++	
++	chunk = buf_pool->chunks;
++    
++	for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
++		buf_block_t*	block		= chunk->blocks;
++    block_page_zip = buf_block_get_page_zip(block);
++
++    for (n_blocks	= chunk->size; n_blocks--; block++) {
++      const buf_frame_t* frame = block->frame;
++
++      if (fil_page_get_type(frame) == FIL_PAGE_TYPE_BLOB) {
++
++        if (UNIV_LIKELY_NULL(block_page_zip)) {
++          part_len = 0; /* hmm, can't figure it out */
++  
++          next_page_no = mach_read_from_4(
++            buf_block_get_frame(block)
++            + FIL_PAGE_NEXT);        
++        } else {
++          part_len = mach_read_from_4(
++            buf_block_get_frame(block)
++            + FIL_PAGE_DATA
++            + 0 /*BTR_BLOB_HDR_PART_LEN*/);
++  
++          next_page_no = mach_read_from_4(
++            buf_block_get_frame(block)
++            + FIL_PAGE_DATA
++            + 4 /*BTR_BLOB_HDR_NEXT_PAGE_NO*/);
++        }
++
++        table->field[0]->store(block->page.space);
++        table->field[1]->store(block->page.offset);
++        table->field[2]->store(block_page_zip != NULL);
++        table->field[3]->store(part_len);
++
++        if(next_page_no == FIL_NULL)
++        {
++          table->field[4]->store(0);
++        } else {
++          table->field[4]->store(block->page.offset);
++        }
++
++        table->field[5]->store(0);
++        table->field[6]->store(block->page.buf_fix_count);
++        table->field[7]->store(block->page.flush_type);
++  
++        if (schema_table_store_record(thd, table)) {
++          status = 1;
++          break;
++        }
++
++      }
++    }      
++	}
++
++	buf_pool_mutex_exit();
++
++	DBUG_RETURN(status);
++}
++
++/***********************************************************************
++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
++static
++int
++i_s_innodb_buffer_pool_pages_init(
++/*=========*/
++			/* out: 0 on success */
++	void*	p)	/* in/out: table schema object */
++{
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_init");
++	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
++
++	schema->fields_info = i_s_innodb_buffer_pool_pages_fields_info;
++	schema->fill_table = i_s_innodb_buffer_pool_pages_fill;
++
++	DBUG_RETURN(0);
++}
++
++/***********************************************************************
++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
++static
++int
++i_s_innodb_buffer_pool_pages_index_init(
++/*=========*/
++			/* out: 0 on success */
++	void*	p)	/* in/out: table schema object */
++{
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_init");
++	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
++
++	schema->fields_info = i_s_innodb_buffer_pool_pages_index_fields_info;
++	schema->fill_table = i_s_innodb_buffer_pool_pages_index_fill;
++
++	DBUG_RETURN(0);
++}
++
++/***********************************************************************
++Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
++static
++int
++i_s_innodb_buffer_pool_pages_blob_init(
++/*=========*/
++			/* out: 0 on success */
++	void*	p)	/* in/out: table schema object */
++{
++	DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_init");
++	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
++
++	schema->fields_info = i_s_innodb_buffer_pool_pages_blob_fields_info;
++	schema->fill_table = i_s_innodb_buffer_pool_pages_blob_fill;
++
++	DBUG_RETURN(0);
++}
++
++
++UNIV_INTERN struct st_mysql_plugin	i_s_innodb_buffer_pool_pages =
++{
++	/* the plugin type (a MYSQL_XXX_PLUGIN value) */
++	/* int */
++	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
++
++	/* pointer to type-specific plugin descriptor */
++	/* void* */
++	STRUCT_FLD(info, &i_s_info),
++
++	/* plugin name */
++	/* const char* */
++	STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
++
++	/* plugin author (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(author, plugin_author),
++
++	/* general descriptive text (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(descr, "InnoDB buffer pool pages"),
++
++	/* the plugin license (PLUGIN_LICENSE_XXX) */
++	/* int */
++	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
++
++	/* the function to invoke when plugin is loaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
++
++	/* the function to invoke when plugin is unloaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(deinit, i_s_common_deinit),
++
++	/* plugin version (for SHOW PLUGINS) */
++	/* unsigned int */
++	STRUCT_FLD(version, 0x0100 /* 1.0 */),
++
++	/* struct st_mysql_show_var* */
++	STRUCT_FLD(status_vars, NULL),
++
++	/* struct st_mysql_sys_var** */
++	STRUCT_FLD(system_vars, NULL),
++
++	/* reserved for dependency checking */
++	/* void* */
++	STRUCT_FLD(__reserved1, NULL)
++};
++
++UNIV_INTERN struct st_mysql_plugin	i_s_innodb_buffer_pool_pages_index =
++{
++	/* the plugin type (a MYSQL_XXX_PLUGIN value) */
++	/* int */
++	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
++
++	/* pointer to type-specific plugin descriptor */
++	/* void* */
++	STRUCT_FLD(info, &i_s_info),
++
++	/* plugin name */
++	/* const char* */
++	STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
++
++	/* plugin author (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(author, plugin_author),
++
++	/* general descriptive text (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
++
++	/* the plugin license (PLUGIN_LICENSE_XXX) */
++	/* int */
++	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
++
++	/* the function to invoke when plugin is loaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
++
++	/* the function to invoke when plugin is unloaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(deinit, i_s_common_deinit),
++
++	/* plugin version (for SHOW PLUGINS) */
++	/* unsigned int */
++	STRUCT_FLD(version, 0x0100 /* 1.0 */),
++
++	/* struct st_mysql_show_var* */
++	STRUCT_FLD(status_vars, NULL),
++
++	/* struct st_mysql_sys_var** */
++	STRUCT_FLD(system_vars, NULL),
++
++	/* reserved for dependency checking */
++	/* void* */
++	STRUCT_FLD(__reserved1, NULL)
++};
++
++UNIV_INTERN struct st_mysql_plugin	i_s_innodb_buffer_pool_pages_blob =
++{
++	/* the plugin type (a MYSQL_XXX_PLUGIN value) */
++	/* int */
++	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
++
++	/* pointer to type-specific plugin descriptor */
++	/* void* */
++	STRUCT_FLD(info, &i_s_info),
++
++	/* plugin name */
++	/* const char* */
++	STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
++
++	/* plugin author (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(author, plugin_author),
++
++	/* general descriptive text (for SHOW PLUGINS) */
++	/* const char* */
++	STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
++
++	/* the plugin license (PLUGIN_LICENSE_XXX) */
++	/* int */
++	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
++
++	/* the function to invoke when plugin is loaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
++
++	/* the function to invoke when plugin is unloaded */
++	/* int (*)(void*); */
++	STRUCT_FLD(deinit, i_s_common_deinit),
++
++	/* plugin version (for SHOW PLUGINS) */
++	/* unsigned int */
++	STRUCT_FLD(version, 0x0100 /* 1.0 */),
++
++	/* struct st_mysql_show_var* */
++	STRUCT_FLD(status_vars, NULL),
++
++	/* struct st_mysql_sys_var** */
++	STRUCT_FLD(system_vars, NULL),
++
++	/* reserved for dependency checking */
++	/* void* */
++	STRUCT_FLD(__reserved1, NULL)
++};
++
++
+ /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
+ static ST_FIELD_INFO	innodb_trx_fields_info[] =
+ {
+diff -ruN a/storage/innodb_plugin/handler/i_s.h b/storage/innodb_plugin/handler/i_s.h
+--- a/storage/innodb_plugin/handler/i_s.h	2010-04-29 15:28:20.000000000 +0900
++++ b/storage/innodb_plugin/handler/i_s.h	2010-04-29 16:04:05.000000000 +0900
+@@ -26,6 +26,9 @@
+ #ifndef i_s_h
+ #define i_s_h
+ 
++extern struct st_mysql_plugin	i_s_innodb_buffer_pool_pages;
++extern struct st_mysql_plugin	i_s_innodb_buffer_pool_pages_index;
++extern struct st_mysql_plugin	i_s_innodb_buffer_pool_pages_blob;
+ extern struct st_mysql_plugin	i_s_innodb_trx;
+ extern struct st_mysql_plugin	i_s_innodb_locks;
+ extern struct st_mysql_plugin	i_s_innodb_lock_waits;
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:03:34.000000000 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:04:05.000000000 +0900
+@@ -27,5 +27,6 @@
+ {"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
+diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
+--- a/storage/innodb_plugin/include/buf0buf.h	2010-07-14 15:57:23.333331973 +0900
++++ b/storage/innodb_plugin/include/buf0buf.h	2010-07-14 16:03:45.885392395 +0900
+@@ -1286,6 +1286,15 @@
+ #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
+ /* @} */
+ 
++/** A chunk of buffers.  The buffer pool is allocated in chunks. */
++struct buf_chunk_struct{
++	ulint		mem_size;	/*!< allocated size of the chunk */
++	ulint		size;		/*!< size of frames[] and blocks[] */
++	void*		mem;		/*!< pointer to the memory area which
++					was allocated for the frames */
++	buf_block_t*	blocks;		/*!< array of buffer control blocks */
++};
++
+ /** @brief The buffer pool statistics structure. */
+ struct buf_pool_stat_struct{
+ 	ulint	n_page_gets;	/*!< number of page gets performed;
diff --git a/mysql-innodb_adjust_defaults.patch b/mysql-innodb_adjust_defaults.patch
new file mode 100644
index 0000000..e08a02b
--- /dev/null
+++ b/mysql-innodb_adjust_defaults.patch
@@ -0,0 +1,48 @@
+# name       : innodb_adjust_defaults.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/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
+@@ -11178,7 +11178,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);
+ 
+ static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
+   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+@@ -11278,7 +11278,7 @@
+ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
+   PLUGIN_VAR_NOCMDARG,
+   "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
+-  NULL, NULL, TRUE);
++  NULL, NULL, FALSE);
+ 
+ static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
+   PLUGIN_VAR_RQCMDARG,
+@@ -11523,7 +11523,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",
+-  NULL, NULL, 0, 0, 1, 0);
++  NULL, NULL, 1, 0, 1, 0);
+ 
+ static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
+   PLUGIN_VAR_RQCMDARG,
+@@ -11601,8 +11601,8 @@
+ };
+ static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
+   PLUGIN_VAR_RQCMDARG,
+-  "Enable/Disable flushing along modified age. ([none], reflex, estimate)",
+-  NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
++  "Enable/Disable flushing along modified age. (none, reflex, [estimate])",
++  NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
+ 
+ static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
+   PLUGIN_VAR_RQCMDARG,
diff --git a/mysql-innodb_admin_command_base.patch b/mysql-innodb_admin_command_base.patch
new file mode 100644
index 0000000..2619ed9
--- /dev/null
+++ b/mysql-innodb_admin_command_base.patch
@@ -0,0 +1,181 @@
+# name       : innodb_admin_command_base.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/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
+@@ -11532,6 +11532,7 @@
+ i_s_innodb_cmpmem_reset,
+ i_s_innodb_table_stats,
+ i_s_innodb_index_stats,
++i_s_innodb_admin_command,
+ i_s_innodb_patches
+ mysql_declare_plugin_end;
+ 
+diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
+--- a/storage/innodb_plugin/handler/i_s.cc	2010-08-27 16:22:04.261021936 +0900
++++ b/storage/innodb_plugin/handler/i_s.cc	2010-08-27 16:27:44.077058655 +0900
+@@ -2948,3 +2948,139 @@
+ 	STRUCT_FLD(system_vars, NULL),
+ 	STRUCT_FLD(__reserved1, NULL)
+ };
++
++/***********************************************************************
++*/
++static ST_FIELD_INFO	i_s_innodb_admin_command_info[] =
++{
++	{STRUCT_FLD(field_name,		"result_message"),
++	 STRUCT_FLD(field_length,	1024),
++	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
++	 STRUCT_FLD(value,		0),
++	 STRUCT_FLD(field_flags,	0),
++	 STRUCT_FLD(old_name,		""),
++	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
++
++	END_OF_ST_FIELD_INFO
++};
++
++#ifndef INNODB_COMPATIBILITY_HOOKS
++#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
++#endif
++
++extern "C" {
++char **thd_query(MYSQL_THD thd);
++}
++
++static
++int
++i_s_innodb_admin_command_fill(
++/*==========================*/
++	THD*		thd,
++	TABLE_LIST*	tables,
++	COND*		cond)
++{
++	TABLE*	i_s_table	= (TABLE *) tables->table;
++	char**	query_str;
++	char*	ptr;
++	char	quote	= '\0';
++	const char*	command_head = "XTRA_";
++
++	DBUG_ENTER("i_s_innodb_admin_command_fill");
++
++	/* deny access to non-superusers */
++	if (check_global_access(thd, PROCESS_ACL)) {
++		DBUG_RETURN(0);
++	}
++
++	if(thd_sql_command(thd) != SQLCOM_SELECT) {
++		field_store_string(i_s_table->field[0],
++			"SELECT command is only accepted.");
++		goto end_func;
++	}
++
++	query_str = thd_query(thd);
++	ptr = *query_str;
++	
++	for (; *ptr; ptr++) {
++		if (*ptr == quote) {
++			quote = '\0';
++		} else if (quote) {
++		} else if (*ptr == '`' || *ptr == '"') {
++			quote = *ptr;
++		} else {
++			long	i;
++			for (i = 0; command_head[i]; i++) {
++				if (toupper((int)(unsigned char)(ptr[i]))
++				    != toupper((int)(unsigned char)
++				      (command_head[i]))) {
++					goto nomatch;
++				}
++			}
++			break;
++nomatch:
++			;
++		}
++	}
++
++	if (!*ptr) {
++		field_store_string(i_s_table->field[0],
++			"No XTRA_* command in the SQL statement."
++			" Please add /*!XTRA_xxxx*/ to the SQL.");
++		goto end_func;
++	}
++
++	if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
++		/* This is example command XTRA_HELLO */
++
++		ut_print_timestamp(stderr);
++		fprintf(stderr, " InnoDB: administration command test for XtraDB"
++				" 'XTRA_HELLO' was detected.\n");
++
++		field_store_string(i_s_table->field[0],
++			"Hello!");
++		goto end_func;
++	}
++
++	field_store_string(i_s_table->field[0],
++		"Undefined XTRA_* command.");
++	goto end_func;
++
++end_func:
++	if (schema_table_store_record(thd, i_s_table)) {
++		DBUG_RETURN(1);
++	} else {
++		DBUG_RETURN(0);
++	}
++}
++
++static
++int
++i_s_innodb_admin_command_init(
++/*==========================*/
++	void*	p)
++{
++	DBUG_ENTER("i_s_innodb_admin_command_init");
++	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
++
++	schema->fields_info = i_s_innodb_admin_command_info;
++	schema->fill_table = i_s_innodb_admin_command_fill;
++
++	DBUG_RETURN(0);
++}
++
++UNIV_INTERN struct st_mysql_plugin	i_s_innodb_admin_command =
++{
++	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(descr, "XtraDB specific command acceptor"),
++	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
++	STRUCT_FLD(init, i_s_innodb_admin_command_init),
++	STRUCT_FLD(deinit, i_s_common_deinit),
++	STRUCT_FLD(version, 0x0100 /* 1.0 */),
++	STRUCT_FLD(status_vars, NULL),
++	STRUCT_FLD(system_vars, NULL),
++	STRUCT_FLD(__reserved1, NULL)
++};
+diff -ruN a/storage/innodb_plugin/handler/i_s.h b/storage/innodb_plugin/handler/i_s.h
+--- a/storage/innodb_plugin/handler/i_s.h	2010-08-27 16:22:04.261987654 +0900
++++ b/storage/innodb_plugin/handler/i_s.h	2010-08-27 16:27:44.079059299 +0900
+@@ -40,5 +40,6 @@
+ extern struct st_mysql_plugin	i_s_innodb_rseg;
+ extern struct st_mysql_plugin	i_s_innodb_table_stats;
+ extern struct st_mysql_plugin	i_s_innodb_index_stats;
++extern struct st_mysql_plugin	i_s_innodb_admin_command;
+ 
+ #endif /* i_s_h */
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:27:30.223001821 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:27:44.074104321 +0900
+@@ -38,5 +38,6 @@
+ {"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
diff --git a/mysql-innodb_deadlock_count.patch b/mysql-innodb_deadlock_count.patch
new file mode 100644
index 0000000..7a33d6a
--- /dev/null
+++ b/mysql-innodb_deadlock_count.patch
@@ -0,0 +1,73 @@
+# name       : innodb_deadlock_count.patch
+# introduced : 11 or before
+# maintainer : Oleg
+#
+#!!! 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/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
+@@ -546,6 +546,8 @@
+   (char*) &export_vars.innodb_data_written,		  SHOW_LONG},
+   {"dblwr_pages_written",
+   (char*) &export_vars.innodb_dblwr_pages_written,	  SHOW_LONG},
++  {"deadlocks",
++  (char*) &export_vars.innodb_deadlocks,                  SHOW_LONG}, 
+   {"dblwr_writes",
+   (char*) &export_vars.innodb_dblwr_writes,		  SHOW_LONG},
+   {"dict_tables",
+diff -ruN a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h
+--- a/storage/innodb_plugin/include/lock0lock.h	2010-08-10 15:32:14.478241628 +0400
++++ b/storage/innodb_plugin/include/lock0lock.h	2010-08-10 15:32:14.926992081 +0400
+@@ -43,6 +43,7 @@
+ #endif /* UNIV_DEBUG */
+ /* Buffer for storing information about the most recent deadlock error */
+ extern FILE*	lock_latest_err_file;
++extern ulint    srv_n_lock_deadlock_count;
+ 
+ /*********************************************************************//**
+ Gets the size of a lock struct.
+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
+@@ -673,6 +673,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*/
++        ulint innodb_deadlocks;                 /* ??? */
+ 	ulint innodb_dblwr_pages_written;	/*!< srv_dblwr_pages_written */
+ 	ulint innodb_dblwr_writes;		/*!< srv_dblwr_writes */
+ 	ibool innodb_have_atomic_builtins;	/*!< HAVE_ATOMIC_BUILTINS */
+diff -ruN a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c
+--- a/storage/innodb_plugin/lock/lock0lock.c	2010-08-10 15:32:14.478241628 +0400
++++ b/storage/innodb_plugin/lock/lock0lock.c	2010-08-10 15:32:14.936991959 +0400
+@@ -3330,6 +3330,7 @@
+ 		break;
+ 
+ 	case LOCK_VICTIM_IS_START:
++		srv_n_lock_deadlock_count++;
+ 		fputs("*** WE ROLL BACK TRANSACTION (2)\n",
+ 		      lock_latest_err_file);
+ 		break;
+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
+@@ -435,7 +435,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;
+-
++UNIV_INTERN ulint               srv_n_lock_deadlock_count       = 0;
+ 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;
+@@ -2146,6 +2146,8 @@
+ 		= UT_LIST_GET_LEN(buf_pool->flush_list);
+ 	export_vars.innodb_buffer_pool_pages_free
+ 		= UT_LIST_GET_LEN(buf_pool->free);
++	export_vars.innodb_deadlocks
++	        = srv_n_lock_deadlock_count;
+ #ifdef UNIV_DEBUG
+ 	export_vars.innodb_buffer_pool_pages_latched
+ 		= buf_get_latched_pages_number();
diff --git a/mysql-innodb_expand_import.patch b/mysql-innodb_expand_import.patch
new file mode 100644
index 0000000..98d9de2
--- /dev/null
+++ b/mysql-innodb_expand_import.patch
@@ -0,0 +1,555 @@
+# name       : innodb_expand_import.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
+--- a/storage/innodb_plugin/fil/fil0fil.c	2010-04-29 15:44:28.000000000 +0900
++++ b/storage/innodb_plugin/fil/fil0fil.c	2010-04-30 10:43:13.000000000 +0900
+@@ -40,6 +40,12 @@
+ #include "dict0dict.h"
+ #include "page0page.h"
+ #include "page0zip.h"
++#include "trx0trx.h"
++#include "trx0sys.h"
++#include "pars0pars.h"
++#include "row0mysql.h"
++#include "row0row.h"
++#include "que0que.h"
+ #ifndef UNIV_HOTBACKUP
+ # include "buf0lru.h"
+ # include "ibuf0ibuf.h"
+@@ -2983,7 +2989,7 @@
+ 	ut_a(!(flags & (~0UL << DICT_TF_BITS)));
+ 
+ 	file = os_file_create_simple_no_error_handling(
+-		filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
++		filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
+ 	if (!success) {
+ 		/* The following call prints an error message */
+ 		os_file_get_last_error(TRUE);
+@@ -3030,6 +3036,464 @@
+ 	space_id = fsp_header_get_space_id(page);
+ 	space_flags = fsp_header_get_flags(page);
+ 
++	if (srv_expand_import
++	    && (space_id != id || space_flags != (flags & ~(~0 << DICT_TF_BITS)))) {
++		ibool		file_is_corrupt = FALSE;
++		byte*		buf3;
++		byte*		descr_page;
++		ibool		descr_is_corrupt = FALSE;
++		dulint		old_id[31];
++		dulint		new_id[31];
++		ulint		root_page[31];
++		ulint		n_index;
++		os_file_t	info_file = -1;
++		char*		info_file_path;
++		ulint	i;
++		int		len;
++		ib_uint64_t	current_lsn;
++		ulint		size_low, size_high, size, free_limit;
++		ib_int64_t	size_bytes, free_limit_bytes;
++		dict_table_t*	table;
++		dict_index_t*	index;
++		fil_system_t*	system;
++		fil_node_t*	node = NULL;
++		fil_space_t*	space;
++
++		buf3 = ut_malloc(2 * UNIV_PAGE_SIZE);
++		descr_page = ut_align(buf3, UNIV_PAGE_SIZE);
++
++		current_lsn = log_get_lsn();
++
++		/* check the header page's consistency */
++		if (buf_page_is_corrupted(page,
++					  dict_table_flags_to_zip_size(space_flags))) {
++			fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath);
++			file_is_corrupt = TRUE;
++			descr_is_corrupt = TRUE;
++		}
++
++		/* store as first descr page */
++		memcpy(descr_page, page, UNIV_PAGE_SIZE);
++
++		/* get free limit (page number) of the table space */
++/* these should be same to the definition in fsp0fsp.c */
++#define FSP_HEADER_OFFSET	FIL_PAGE_DATA
++#define	FSP_FREE_LIMIT		12
++		free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page);
++		free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)UNIV_PAGE_SIZE;
++
++		/* overwrite fsp header */
++		fsp_header_init_fields(page, id, flags);
++		mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
++		space_id = id;
++		space_flags = flags;
++		if (mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
++			mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
++		mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
++				srv_use_checksums
++				? buf_calc_page_new_checksum(page)
++						: BUF_NO_CHECKSUM_MAGIC);
++		mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
++				srv_use_checksums
++				? buf_calc_page_old_checksum(page)
++						: BUF_NO_CHECKSUM_MAGIC);
++		success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
++
++		/* get file size */
++		os_file_get_size(file, &size_low, &size_high);
++		size_bytes = (((ib_int64_t)size_high) << 32)
++				+ (ib_int64_t)size_low;
++
++		if (size_bytes < free_limit_bytes) {
++			free_limit_bytes = size_bytes;
++			fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
++			file_is_corrupt = TRUE;
++		}
++
++		/* get cruster index information */
++		table = dict_table_get_low(name);
++		index = dict_table_get_first_index(table);
++		ut_a(index->page==3);
++
++		/* read metadata from .exp file */
++		n_index = 0;
++		memset(old_id, 0, sizeof(old_id));
++		memset(new_id, 0, sizeof(new_id));
++		memset(root_page, 0, sizeof(root_page));
++
++		info_file_path = fil_make_ibd_name(name, FALSE);
++		len = strlen(info_file_path);
++		info_file_path[len - 3] = 'e';
++		info_file_path[len - 2] = 'x';
++		info_file_path[len - 1] = 'p';
++
++		info_file = os_file_create_simple_no_error_handling(
++				info_file_path, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
++		if (!success) {
++			fprintf(stderr, "InnoDB: cannot open %s\n", info_file_path);
++			file_is_corrupt = TRUE;
++			goto skip_info;
++		}
++		success = os_file_read(info_file, page, 0, 0, UNIV_PAGE_SIZE);
++		if (!success) {
++			fprintf(stderr, "InnoDB: cannot read %s\n", info_file_path);
++			file_is_corrupt = TRUE;
++			goto skip_info;
++		}
++		if (mach_read_from_4(page) != 0x78706f72UL
++		    || mach_read_from_4(page + 4) != 0x74696e66UL) {
++			fprintf(stderr, "InnoDB: %s seems not to be a correct .exp file\n", info_file_path);
++			file_is_corrupt = TRUE;
++			goto skip_info;
++		}
++
++		fprintf(stderr, "InnoDB: import: extended import of %s is started.\n", name);
++
++		n_index = mach_read_from_4(page + 8);
++		fprintf(stderr, "InnoDB: import: %lu indexes are detected.\n", (ulong)n_index);
++		for (i = 0; i < n_index; i++) {
++			new_id[i] =
++				dict_table_get_index_on_name(table,
++						(char*)(page + (i + 1) * 512 + 12))->id;
++			old_id[i] = mach_read_from_8(page + (i + 1) * 512);
++			root_page[i] = mach_read_from_4(page + (i + 1) * 512 + 8);
++		}
++
++skip_info:
++		if (info_file != -1)
++			os_file_close(info_file);
++
++		/*
++		if (size_bytes >= 1024 * 1024) {
++			size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
++		}
++		*/
++		if (!(flags & DICT_TF_ZSSIZE_MASK)) {
++			mem_heap_t*	heap = NULL;
++			ulint		offsets_[REC_OFFS_NORMAL_SIZE];
++			ulint*		offsets = offsets_;
++			ib_int64_t	offset;
++
++			size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
++			/* over write space id of all pages */
++			rec_offs_init(offsets_);
++
++			fprintf(stderr, "InnoDB: Progress in %%:");
++
++			for (offset = 0; offset < free_limit_bytes; offset += UNIV_PAGE_SIZE) {
++				ulint		checksum_field;
++				ulint		old_checksum_field;
++				ibool		page_is_corrupt;
++
++				success = os_file_read(file, page,
++							(ulint)(offset & 0xFFFFFFFFUL),
++							(ulint)(offset >> 32), UNIV_PAGE_SIZE);
++
++				page_is_corrupt = FALSE;
++
++				/* check consistency */
++				if (memcmp(page + FIL_PAGE_LSN + 4,
++					   page + UNIV_PAGE_SIZE
++					   - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
++
++					page_is_corrupt = TRUE;
++				}
++
++				if (mach_read_from_4(page + FIL_PAGE_OFFSET)
++				    != offset / UNIV_PAGE_SIZE) {
++
++					page_is_corrupt = TRUE;
++				}
++
++				checksum_field = mach_read_from_4(page
++								  + FIL_PAGE_SPACE_OR_CHKSUM);
++
++				old_checksum_field = mach_read_from_4(
++					page + UNIV_PAGE_SIZE
++					- FIL_PAGE_END_LSN_OLD_CHKSUM);
++
++				if (old_checksum_field != mach_read_from_4(page
++									   + FIL_PAGE_LSN)
++				    && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
++				    && old_checksum_field
++				    != buf_calc_page_old_checksum(page)) {
++
++					page_is_corrupt = TRUE;
++				}
++
++				if (checksum_field != 0
++				    && checksum_field != BUF_NO_CHECKSUM_MAGIC
++				    && checksum_field
++				    != buf_calc_page_new_checksum(page)) {
++
++					page_is_corrupt = TRUE;
++				}
++
++				/* if it is free page, inconsistency is acceptable */
++				if (!offset) {
++					/* header page*/
++					/* it should be overwritten already */
++					ut_a(!page_is_corrupt);
++
++				} else if (!((offset / UNIV_PAGE_SIZE) % UNIV_PAGE_SIZE)) {
++					/* descr page (not header) */
++					if (page_is_corrupt) {
++						file_is_corrupt = TRUE;
++						descr_is_corrupt = TRUE;
++					} else {
++						ut_a(fil_page_get_type(page) == FIL_PAGE_TYPE_XDES);
++						descr_is_corrupt = FALSE;
++					}
++
++					/* store as descr page */
++					memcpy(descr_page, page, UNIV_PAGE_SIZE);
++
++				} else if (descr_is_corrupt) {
++					/* unknown state of the page */
++					if (page_is_corrupt) {
++						file_is_corrupt = TRUE;
++					}
++
++				} else {
++					/* check free page or not */
++					/* These definitions should be same to fsp0fsp.c */
++#define	FSP_HEADER_SIZE		(32 + 5 * FLST_BASE_NODE_SIZE)
++
++#define	XDES_BITMAP		(FLST_NODE_SIZE + 12)
++#define	XDES_BITS_PER_PAGE	2
++#define	XDES_FREE_BIT		0
++#define	XDES_SIZE							\
++	(XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
++#define	XDES_ARR_OFFSET		(FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
++
++					/*descr = descr_page + XDES_ARR_OFFSET + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset)*/
++					/*xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)*/
++					byte*	descr;
++					ulint	index;
++					ulint	byte_index;
++					ulint	bit_index;
++
++					descr = descr_page + XDES_ARR_OFFSET
++						+ XDES_SIZE * (ut_2pow_remainder((offset / UNIV_PAGE_SIZE), UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE);
++
++					index = XDES_FREE_BIT + XDES_BITS_PER_PAGE * ((offset / UNIV_PAGE_SIZE) % FSP_EXTENT_SIZE);
++					byte_index = index / 8;
++					bit_index = index % 8;
++
++					if (ut_bit_get_nth(mach_read_from_1(descr + XDES_BITMAP + byte_index), bit_index)) {
++						/* free page */
++						if (page_is_corrupt) {
++							goto skip_write;
++						}
++					} else {
++						/* not free */
++						if (page_is_corrupt) {
++							file_is_corrupt = TRUE;
++						}
++					}
++				}
++
++				if (page_is_corrupt) {
++					fprintf(stderr, " [errp:%lld]", offset / UNIV_PAGE_SIZE);
++
++					/* cannot treat corrupt page */
++					goto skip_write;
++				}
++
++				if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
++					mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
++
++					for (i = 0; i < n_index; i++) {
++						if (offset / UNIV_PAGE_SIZE == root_page[i]) {
++							/* this is index root page */
++							mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
++											+ FSEG_HDR_SPACE, id);
++							mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
++											+ FSEG_HDR_SPACE, id);
++							break;
++						}
++					}
++
++					if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
++						dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
++
++						if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
++						    && ut_dulint_cmp(old_id[0], tmp) == 0) {
++							/* leaf page of cluster index, reset trx_id of records */
++							rec_t*	rec;
++							rec_t*	supremum;
++							ulint	n_recs;
++
++							supremum = page_get_supremum_rec(page);
++							rec = page_rec_get_next(page_get_infimum_rec(page));
++							n_recs = page_get_n_recs(page);
++
++							while (rec && rec != supremum && n_recs > 0) {
++								ulint	n_fields;
++								ulint	i;
++								ulint	offset = index->trx_id_offset;
++								offsets = rec_get_offsets(rec, index, offsets,
++										ULINT_UNDEFINED, &heap);
++								n_fields = rec_offs_n_fields(offsets);
++								if (!offset) {
++									offset = row_get_trx_id_offset(rec, index, offsets);
++								}
++								trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
++
++								for (i = 0; i < n_fields; i++) {
++									if (rec_offs_nth_extern(offsets, i)) {
++										ulint	local_len;
++										byte*	data;
++
++										data = rec_get_nth_field(rec, offsets, i, &local_len);
++
++										local_len -= BTR_EXTERN_FIELD_REF_SIZE;
++
++										mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
++									}
++								}
++
++								rec = page_rec_get_next(rec);
++								n_recs--;
++							}
++						}
++
++						for (i = 0; i < n_index; i++) {
++							if (ut_dulint_cmp(old_id[i], tmp) == 0) {
++								mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]);
++								break;
++							}
++						}
++					}
++
++					if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
++						mach_write_ull(page + FIL_PAGE_LSN, current_lsn);
++						mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
++										current_lsn);
++					}
++
++					mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
++							srv_use_checksums
++							? buf_calc_page_new_checksum(page)
++									: BUF_NO_CHECKSUM_MAGIC);
++					mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
++							srv_use_checksums
++							? buf_calc_page_old_checksum(page)
++									: BUF_NO_CHECKSUM_MAGIC);
++
++					success = os_file_write(filepath, file, page,
++								(ulint)(offset & 0xFFFFFFFFUL),
++								(ulint)(offset >> 32), UNIV_PAGE_SIZE);
++				}
++
++skip_write:
++				if (free_limit_bytes
++				    && ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes)
++					!= ((offset * 100) / free_limit_bytes)) {
++					fprintf(stderr, " %lu",
++						(ulong)((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes));
++				}
++			}
++
++			fprintf(stderr, " done.\n");
++
++			/* update SYS_INDEXES set root page */
++			index = dict_table_get_first_index(table);
++			while (index) {
++				for (i = 0; i < n_index; i++) {
++					if (ut_dulint_cmp(new_id[i], index->id) == 0) {
++						break;
++					}
++				}
++
++				if (i != n_index
++				    && root_page[i] != index->page) {
++					/* must update */
++					ulint	error;
++					trx_t*	trx;
++					pars_info_t*	info = NULL;
++
++					trx = trx_allocate_for_mysql();
++					trx->op_info = "extended import";
++
++					info = pars_info_create();
++
++					pars_info_add_dulint_literal(info, "indexid", new_id[i]);
++					pars_info_add_int4_literal(info, "new_page", (lint) root_page[i]);
++
++					error = que_eval_sql(info,
++						"PROCEDURE UPDATE_INDEX_PAGE () IS\n"
++						"BEGIN\n"
++						"UPDATE SYS_INDEXES"
++						" SET PAGE_NO = :new_page"
++						" WHERE ID = :indexid;\n"
++						"COMMIT WORK;\n"
++						"END;\n",
++						FALSE, trx);
++
++					if (error != DB_SUCCESS) {
++						fprintf(stderr, "InnoDB: failed to update SYS_INDEXES\n");
++					}
++
++					trx_commit_for_mysql(trx);
++
++					trx_free_for_mysql(trx);
++
++					index->page = root_page[i];
++				}
++
++				index = dict_table_get_next_index(index);
++			}
++			if (UNIV_LIKELY_NULL(heap)) {
++				mem_heap_free(heap);
++			}
++		} else {
++			/* zip page? */
++			size = (ulint)
++			(size_bytes
++					/ dict_table_flags_to_zip_size(flags));
++			fprintf(stderr, "InnoDB: import: table %s seems to be in newer format."
++					" It may not be able to treated for now.\n", name);
++		}
++		/* .exp file should be removed */
++		success = os_file_delete(info_file_path);
++		if (!success) {
++			success = os_file_delete_if_exists(info_file_path);
++		}
++		mem_free(info_file_path);
++
++		system	= fil_system;
++		mutex_enter(&(system->mutex));
++		space = fil_space_get_by_id(id);
++		if (space)
++			node = UT_LIST_GET_FIRST(space->chain);
++		if (node && node->size < size) {
++			space->size += (size - node->size);
++			node->size = size;
++		}
++		mutex_exit(&(system->mutex));
++
++		ut_free(buf3);
++
++		if (file_is_corrupt) {
++			ut_print_timestamp(stderr);
++			fputs("  InnoDB: Error: file ",
++			      stderr);
++			ut_print_filename(stderr, filepath);
++			fprintf(stderr, " seems to be corrupt.\n"
++				"InnoDB: anyway, all not corrupt pages were tried to be converted to salvage.\n"
++				"InnoDB: ##### CAUTION #####\n"
++				"InnoDB: ## The .ibd must cause to crash InnoDB, though re-import would seem to be succeeded.\n"
++				"InnoDB: ## If you don't have knowledge about salvaging data from .ibd, you should not use the file.\n"
++				"InnoDB: ###################\n");
++			success = FALSE;
++
++			ut_free(buf2);
++
++			goto func_exit;
++		}
++	}
++
+ 	ut_free(buf2);
+ 
+ 	if (UNIV_UNLIKELY(space_id != id
+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
+@@ -11305,6 +11305,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);
+ 
++static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
++  PLUGIN_VAR_RQCMDARG,
++  "Enable/Disable converting automatically *.ibd files when import tablespace.",
++  NULL, NULL, 0, 0, 1, 0);
++
+ 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.",
+@@ -11381,6 +11386,7 @@
+   MYSQL_SYSVAR(adaptive_checkpoint),
+   MYSQL_SYSVAR(flush_log_at_trx_commit_session),
+   MYSQL_SYSVAR(enable_unsafe_group_commit),
++  MYSQL_SYSVAR(expand_import),
+   MYSQL_SYSVAR(extra_rsegments),
+   MYSQL_SYSVAR(dict_size_limit),
+   MYSQL_SYSVAR(use_sys_malloc),
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 18:58:20.000000000 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-30 10:28:05.000000000 +0900
+@@ -32,6 +32,7 @@
+ {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
+ {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
++{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+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 @@
+ extern ulint	srv_read_ahead;
+ extern ulint	srv_adaptive_checkpoint;
+ 
++extern ulint	srv_expand_import;
++
+ extern ulint	srv_extra_rsegments;
+ extern ulint	srv_dict_size_limit;
+ /*-------------------------------------------*/
+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 @@
+ 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 */
+ 
++UNIV_INTERN ulint	srv_expand_import = 0; /* 0:disable 1:enable */
++
+ UNIV_INTERN ulint	srv_extra_rsegments = 0; /* extra rseg for users */
+ UNIV_INTERN ulint	srv_dict_size_limit = 0;
+ /*-------------------------------------------*/
diff --git a/mysql-innodb_expand_undo_slots.patch b/mysql-innodb_expand_undo_slots.patch
new file mode 100644
index 0000000..29a07e8
--- /dev/null
+++ b/mysql-innodb_expand_undo_slots.patch
@@ -0,0 +1,150 @@
+# name       : innodb_expand_undo_slots.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
+--- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:06:22.000000000 +0900
++++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:06:59.000000000 +0900
+@@ -165,6 +165,7 @@
+ #endif /* UNIV_LOG_ARCHIVE */
+ static my_bool	innobase_use_doublewrite		= TRUE;
+ static my_bool	innobase_use_checksums			= TRUE;
++static my_bool	innobase_extra_undoslots		= FALSE;
+ 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 @@
+ 		goto error;
+ 	}
+ 
++	srv_extra_undoslots = (ibool) innobase_extra_undoslots;
++
+ 	/* -------------- Log files ---------------------------*/
+ 
+ 	/* The default dir for log files is the datadir of MySQL */
+@@ -10712,6 +10715,13 @@
+   "The common part for InnoDB table spaces.",
+   NULL, NULL, NULL);
+ 
++static MYSQL_SYSVAR_BOOL(extra_undoslots, innobase_extra_undoslots,
++  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
++  "Enable to use about 4000 undo slots instead of default 1024. "
++  "#### Attention: Once you enable this parameter, "
++  "don't use the datafile for normal mysqld or ibbackup! ####",
++  NULL, NULL, FALSE);
++
+ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
+   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+   "Enable InnoDB doublewrite buffer (enabled by default). "
+@@ -11095,6 +11105,7 @@
+   MYSQL_SYSVAR(data_file_path),
+   MYSQL_SYSVAR(data_home_dir),
+   MYSQL_SYSVAR(doublewrite),
++  MYSQL_SYSVAR(extra_undoslots),
+   MYSQL_SYSVAR(fast_shutdown),
+   MYSQL_SYSVAR(file_io_threads),
+   MYSQL_SYSVAR(read_io_threads),
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:06:22.000000000 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:06:59.000000000 +0900
+@@ -28,5 +28,6 @@
+ {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
+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 15:55:25.000000000 +0900
++++ b/storage/innodb_plugin/include/srv0srv.h	2010-04-29 16:06:59.000000000 +0900
+@@ -112,6 +112,8 @@
+ extern ulint*	srv_data_file_sizes;
+ extern ulint*	srv_data_file_is_raw_partition;
+ 
++extern ibool	srv_extra_undoslots;
++
+ extern ibool	srv_auto_extend_last_data_file;
+ extern ulint	srv_last_file_size_max;
+ extern char**	srv_log_group_home_dirs;
+diff -ruN a/storage/innodb_plugin/include/trx0rseg.h b/storage/innodb_plugin/include/trx0rseg.h
+--- a/storage/innodb_plugin/include/trx0rseg.h	2010-04-06 23:07:13.000000000 +0900
++++ b/storage/innodb_plugin/include/trx0rseg.h	2010-04-29 16:06:59.000000000 +0900
+@@ -123,8 +123,11 @@
+ 	trx_rseg_t*	rseg);		/* in, own: instance to free */
+ 
+ 
++/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
++#define TRX_RSEG_N_EXTRA_SLOTS	(((UNIV_PAGE_SIZE - (FIL_PAGE_DATA + FIL_PAGE_DATA_END + TRX_RSEG_UNDO_SLOTS)) / TRX_RSEG_SLOT_SIZE) - 4)
++
+ /* Number of undo log slots in a rollback segment file copy */
+-#define TRX_RSEG_N_SLOTS	(UNIV_PAGE_SIZE / 16)
++#define TRX_RSEG_N_SLOTS	(srv_extra_undoslots ? TRX_RSEG_N_EXTRA_SLOTS : (UNIV_PAGE_SIZE / 16))
+ 
+ /* Maximum number of transactions supported by a single rollback segment */
+ #define TRX_RSEG_MAX_N_TRXS	(TRX_RSEG_N_SLOTS / 2)
+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 15:55:25.000000000 +0900
++++ b/storage/innodb_plugin/srv/srv0srv.c	2010-04-29 16:06:59.000000000 +0900
+@@ -142,6 +142,8 @@
+ /* size in database pages */
+ UNIV_INTERN ulint*	srv_data_file_sizes = NULL;
+ 
++UNIV_INTERN ibool	srv_extra_undoslots = FALSE;
++
+ /* 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
+diff -ruN a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c
+--- a/storage/innodb_plugin/trx/trx0undo.c	2010-04-06 23:07:14.000000000 +0900
++++ b/storage/innodb_plugin/trx/trx0undo.c	2010-04-29 16:06:59.000000000 +0900
+@@ -1395,9 +1395,47 @@
+ 	rseg_header = trx_rsegf_get_new(rseg->space, rseg->zip_size,
+ 					rseg->page_no, &mtr);
+ 
++	if (!srv_extra_undoslots) {
++		/* uses direct call for avoid "Assertion failure" */
++		//page_no = trx_rsegf_get_nth_undo(rseg_header, TRX_RSEG_N_EXTRA_SLOTS - 1, &mtr);
++		page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
++					 + (TRX_RSEG_N_EXTRA_SLOTS - 1) * TRX_RSEG_SLOT_SIZE,
++					 MLOG_4BYTES, &mtr);
++		if (page_no != 0) {
++			/* check extended slots are not used */
++			for (i = TRX_RSEG_N_SLOTS; i < TRX_RSEG_N_EXTRA_SLOTS; i++) {
++				/* uses direct call for avoid "Assertion failure" */
++				page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
++							 + i * TRX_RSEG_SLOT_SIZE,
++							 MLOG_4BYTES, &mtr);
++				if (page_no != 0 && page_no != FIL_NULL) {
++					srv_extra_undoslots = TRUE;
++					fprintf(stderr,
++"InnoDB: Error: innodb_extra_undoslots option is disabled, but it was enabled before.\n"
++"InnoDB: The datafile is not normal for mysqld and disabled innodb_extra_undoslots.\n"
++"InnoDB: Enable innodb_extra_undoslots if it was enabled before, and\n"
++"InnoDB: ### don't use this datafile with other mysqld or ibbackup! ###\n"
++"InnoDB: Cannot continue operation for the safety. Calling exit(1).\n");
++					exit(1);
++				}
++			}
++			fprintf(stderr,
++"InnoDB: Warning: innodb_extra_undoslots option is disabled, but it was  enabled before.\n"
++"InnoDB: But extended undo slots seem not used, so continue operation.\n");
++		}
++	}
++
+ 	for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
+ 		page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);
+ 
++		/* If it was not initialized when the datafile created,
++		page_no will be 0 for the extended slots after that */
++
++		if (page_no == 0) {
++			page_no = FIL_NULL;
++			trx_rsegf_set_nth_undo(rseg_header, i, page_no, &mtr);
++		}
++
+ 		/* In forced recovery: try to avoid operations which look
+ 		at database pages; undo logs are rapidly changing data, and
+ 		the probability that they are in an inconsistent state is
diff --git a/mysql-innodb_fast_checksum.patch b/mysql-innodb_fast_checksum.patch
new file mode 100644
index 0000000..4d830c9
--- /dev/null
+++ b/mysql-innodb_fast_checksum.patch
@@ -0,0 +1,311 @@
+# name       : innodb_fast_checksum.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
+--- a/storage/innodb_plugin/buf/buf0buf.c	2010-08-27 16:40:36.508988536 +0900
++++ b/storage/innodb_plugin/buf/buf0buf.c	2010-08-27 16:42:03.596041861 +0900
+@@ -343,6 +343,27 @@
+ 	return(checksum);
+ }
+ 
++UNIV_INTERN
++ulint
++buf_calc_page_new_checksum_32(
++/*==========================*/
++	const byte*	page)	/*!< in: buffer page */
++{
++	ulint checksum;
++
++	checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
++				  FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
++		+ ut_fold_binary(page + FIL_PAGE_DATA,
++				 FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA)
++		+ ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32,
++				    UNIV_PAGE_SIZE - FIL_PAGE_DATA_ALIGN_32
++				    - FIL_PAGE_END_LSN_OLD_CHKSUM);
++
++	checksum = checksum & 0xFFFFFFFFUL;
++
++	return(checksum);
++}
++
+ /********************************************************************//**
+ In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
+ looked at the first few bytes of the page. This calculates that old
+@@ -457,9 +478,21 @@
+ 		/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
+ 		(always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
+ 
+-		if (checksum_field != 0
++		if (!srv_fast_checksum
++		    && checksum_field != 0
++		    && checksum_field != BUF_NO_CHECKSUM_MAGIC
++		    && checksum_field
++		    != buf_calc_page_new_checksum(read_buf)) {
++
++			return(TRUE);
++		}
++
++		if (srv_fast_checksum
++		    && checksum_field != 0
+ 		    && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ 		    && checksum_field
++		    != buf_calc_page_new_checksum_32(read_buf)
++		    && checksum_field
+ 		    != buf_calc_page_new_checksum(read_buf)) {
+ 
+ 			return(TRUE);
+@@ -483,6 +516,7 @@
+ 	dict_index_t*	index;
+ #endif /* !UNIV_HOTBACKUP */
+ 	ulint		checksum;
++	ulint		checksum_32;
+ 	ulint		old_checksum;
+ 	ulint		size	= zip_size;
+ 
+@@ -569,12 +603,14 @@
+ 
+ 	checksum = srv_use_checksums
+ 		? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
++	checksum_32 = srv_use_checksums
++		? buf_calc_page_new_checksum_32(read_buf) : BUF_NO_CHECKSUM_MAGIC;
+ 	old_checksum = srv_use_checksums
+ 		? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
+ 
+ 	ut_print_timestamp(stderr);
+ 	fprintf(stderr,
+-		"  InnoDB: Page checksum %lu, prior-to-4.0.14-form"
++		"  InnoDB: Page checksum %lu (32bit_calc: %lu), prior-to-4.0.14-form"
+ 		" checksum %lu\n"
+ 		"InnoDB: stored checksum %lu, prior-to-4.0.14-form"
+ 		" stored checksum %lu\n"
+@@ -583,7 +619,7 @@
+ 		"InnoDB: Page number (if stored to page already) %lu,\n"
+ 		"InnoDB: space id (if created with >= MySQL-4.1.1"
+ 		" and stored already) %lu\n",
+-		(ulong) checksum, (ulong) old_checksum,
++		(ulong) checksum, (ulong) checksum_32, (ulong) old_checksum,
+ 		(ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
+ 		(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+ 					 - FIL_PAGE_END_LSN_OLD_CHKSUM),
+diff -ruN a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c
+--- a/storage/innodb_plugin/buf/buf0flu.c	2010-08-27 16:38:38.226023489 +0900
++++ b/storage/innodb_plugin/buf/buf0flu.c	2010-08-27 16:42:03.597411439 +0900
+@@ -957,7 +957,9 @@
+ 
+ 	mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ 			srv_use_checksums
+-			? buf_calc_page_new_checksum(page)
++			? (!srv_fast_checksum
++			   ? buf_calc_page_new_checksum(page)
++			   : buf_calc_page_new_checksum_32(page))
+ 			: BUF_NO_CHECKSUM_MAGIC);
+ 
+ 	/* We overwrite the first 4 bytes of the end lsn field to store
+diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
+--- a/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:40:36.522990504 +0900
++++ b/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:42:03.602023484 +0900
+@@ -3096,7 +3096,9 @@
+ 			mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
+ 		mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ 				srv_use_checksums
+-				? buf_calc_page_new_checksum(page)
++				? (!srv_fast_checksum
++				   ? buf_calc_page_new_checksum(page)
++				   : buf_calc_page_new_checksum_32(page))
+ 						: BUF_NO_CHECKSUM_MAGIC);
+ 		mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ 				srv_use_checksums
+@@ -3226,7 +3228,8 @@
+ 					page_is_corrupt = TRUE;
+ 				}
+ 
+-				if (checksum_field != 0
++				if (!srv_fast_checksum
++				    && checksum_field != 0
+ 				    && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ 				    && checksum_field
+ 				    != buf_calc_page_new_checksum(page)) {
+@@ -3234,6 +3237,17 @@
+ 					page_is_corrupt = TRUE;
+ 				}
+ 
++				if (srv_fast_checksum
++				    && checksum_field != 0
++				    && checksum_field != BUF_NO_CHECKSUM_MAGIC
++				    && checksum_field
++				    != buf_calc_page_new_checksum_32(page)
++				    && checksum_field
++				    != buf_calc_page_new_checksum(page)) {
++
++					page_is_corrupt = TRUE;
++				}
++
+ 				/* if it is free page, inconsistency is acceptable */
+ 				if (!offset) {
+ 					/* header page*/
+@@ -3379,7 +3393,9 @@
+ 
+ 					mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ 							srv_use_checksums
+-							? buf_calc_page_new_checksum(page)
++							? (!srv_fast_checksum
++							   ? buf_calc_page_new_checksum(page)
++							   : buf_calc_page_new_checksum_32(page))
+ 									: BUF_NO_CHECKSUM_MAGIC);
+ 					mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ 							srv_use_checksums
+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:40:36.538021443 +0900
++++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:42:03.611021803 +0900
+@@ -185,6 +185,7 @@
+ #endif /* UNIV_LOG_ARCHIVE */
+ static my_bool	innobase_use_doublewrite		= TRUE;
+ static my_bool	innobase_use_checksums			= TRUE;
++static my_bool	innobase_fast_checksum			= FALSE;
+ 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 @@
+ 
+ 	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
+ 	srv_use_checksums = (ibool) innobase_use_checksums;
++	srv_fast_checksum = (ibool) innobase_fast_checksum;
+ 
+ #ifdef HAVE_LARGE_PAGES
+         if ((os_use_large_pages = (ibool) my_use_large_pages))
+@@ -11105,6 +11107,15 @@
+   "Disable with --skip-innodb-checksums.",
+   NULL, NULL, TRUE);
+ 
++static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
++  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
++  "Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
++  "The original checksum is checked after the new one. It may be slow for reading page"
++  " which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
++  "if you want the entire benefit for performance at once. "
++  "#### Attention: The checksum is not compatible for normal or disabled version! ####",
++  NULL, NULL, FALSE);
++
+ static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
+   PLUGIN_VAR_READONLY,
+   "The common part for InnoDB table spaces.",
+@@ -11595,6 +11606,7 @@
+   MYSQL_SYSVAR(autoextend_increment),
+   MYSQL_SYSVAR(buffer_pool_size),
+   MYSQL_SYSVAR(checksums),
++  MYSQL_SYSVAR(fast_checksum),
+   MYSQL_SYSVAR(commit_concurrency),
+   MYSQL_SYSVAR(concurrency_tickets),
+   MYSQL_SYSVAR(data_file_path),
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:40:36.560063279 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:42:03.615988127 +0900
+@@ -44,5 +44,6 @@
+ {"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
+diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
+--- a/storage/innodb_plugin/include/buf0buf.h	2010-08-27 16:40:36.563059330 +0900
++++ b/storage/innodb_plugin/include/buf0buf.h	2010-08-27 16:42:03.638058638 +0900
+@@ -477,6 +477,11 @@
+ buf_calc_page_new_checksum(
+ /*=======================*/
+ 	const byte*	page);	/*!< in: buffer page */
++UNIV_INTERN
++ulint
++buf_calc_page_new_checksum_32(
++/*==========================*/
++	const byte*	page);	/*!< in: buffer page */
+ /********************************************************************//**
+ In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
+ looked at the first few bytes of the page. This calculates that old
+diff -ruN a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h
+--- a/storage/innodb_plugin/include/fil0fil.h	2010-08-27 16:40:36.572063042 +0900
++++ b/storage/innodb_plugin/include/fil0fil.h	2010-08-27 16:42:03.640021168 +0900
+@@ -117,6 +117,7 @@
+ #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID  34 /*!< starting from 4.1.x this
+ 					contains the space id of the page */
+ #define FIL_PAGE_DATA		38	/*!< start of the data on the page */
++#define FIL_PAGE_DATA_ALIGN_32	40
+ /* @} */
+ /** File page trailer @{ */
+ #define FIL_PAGE_END_LSN_OLD_CHKSUM 8	/*!< the low 4 bytes of this are used
+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 @@
+ 
+ extern ibool	srv_use_doublewrite_buf;
+ extern ibool	srv_use_checksums;
++extern ibool	srv_fast_checksum;
+ 
+ extern ibool	srv_set_thread_priorities;
+ extern int	srv_query_thread_priority;
+diff -ruN a/storage/innodb_plugin/include/ut0rnd.h b/storage/innodb_plugin/include/ut0rnd.h
+--- a/storage/innodb_plugin/include/ut0rnd.h	2010-08-04 02:24:20.000000000 +0900
++++ b/storage/innodb_plugin/include/ut0rnd.h	2010-08-27 16:42:03.642990139 +0900
+@@ -124,6 +124,13 @@
+ 	const byte*	str,	/*!< in: string of bytes */
+ 	ulint		len)	/*!< in: length */
+ 	__attribute__((pure));
++UNIV_INLINE
++ulint
++ut_fold_binary_32(
++/*==============*/
++	const byte*	str,	/*!< in: string of bytes */
++	ulint		len)	/*!< in: length */
++	__attribute__((pure));
+ /***********************************************************//**
+ Looks for a prime number slightly greater than the given argument.
+ The prime is chosen so that it is not near any power of 2.
+diff -ruN a/storage/innodb_plugin/include/ut0rnd.ic b/storage/innodb_plugin/include/ut0rnd.ic
+--- a/storage/innodb_plugin/include/ut0rnd.ic	2010-08-04 02:24:20.000000000 +0900
++++ b/storage/innodb_plugin/include/ut0rnd.ic	2010-08-27 16:42:03.643990557 +0900
+@@ -226,3 +226,28 @@
+ 
+ 	return(fold);
+ }
++
++UNIV_INLINE
++ulint
++ut_fold_binary_32(
++/*==============*/
++	const byte*	str,	/*!< in: string of bytes */
++	ulint		len)	/*!< in: length */
++{
++	const ib_uint32_t*	str_end = (const ib_uint32_t*) (str + len);
++	const ib_uint32_t*	str_32 = (const ib_uint32_t*) str;
++	ulint			fold = 0;
++
++	ut_ad(str);
++	/* This function is only for word-aligned data */
++	ut_ad(len % 4 == 0);
++	ut_ad((ulint)str % 4 == 0);
++
++	while (str_32 < str_end) {
++		fold = ut_fold_ulint_pair(fold, (ulint)(*str_32));
++
++		str_32++;
++	}
++
++	return(fold);
++}
+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 @@
+ 
+ UNIV_INTERN ibool	srv_use_doublewrite_buf	= TRUE;
+ UNIV_INTERN ibool	srv_use_checksums = TRUE;
++UNIV_INTERN ibool	srv_fast_checksum = FALSE;
+ 
+ UNIV_INTERN ibool	srv_set_thread_priorities = TRUE;
+ UNIV_INTERN int	srv_query_thread_priority = 0;
diff --git a/mysql-innodb_files_extend.patch b/mysql-innodb_files_extend.patch
new file mode 100644
index 0000000..513a5d8
--- /dev/null
+++ b/mysql-innodb_files_extend.patch
@@ -0,0 +1,422 @@
+# name       : innodb_files_extend.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/buf/buf0buddy.c b/storage/innodb_plugin/buf/buf0buddy.c
+--- a/storage/innodb_plugin/buf/buf0buddy.c	2010-08-27 16:13:11.055058310 +0900
++++ b/storage/innodb_plugin/buf/buf0buddy.c	2010-08-27 16:44:21.664059035 +0900
+@@ -43,7 +43,7 @@
+ #endif /* UNIV_DEBUG */
+ /** Statistics of the buddy system, indexed by block size.
+ Protected by buf_pool_mutex. */
+-UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
++UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
+ 
+ /**********************************************************************//**
+ Get the offset of the buddy of a compressed page frame.
+diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
+--- a/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:43:11.941989968 +0900
++++ b/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:44:21.668058937 +0900
+@@ -4722,9 +4722,9 @@
+ 	ut_ad(ut_is_2pow(zip_size));
+ 	ut_ad(buf);
+ 	ut_ad(len > 0);
+-#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
+-# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
+-#endif
++//#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
++//# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
++//#endif
+ 	ut_ad(fil_validate());
+ #ifndef UNIV_HOTBACKUP
+ # ifndef UNIV_LOG_DEBUG
+diff -ruN a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c
+--- a/storage/innodb_plugin/fsp/fsp0fsp.c	2010-08-27 16:40:36.528021375 +0900
++++ b/storage/innodb_plugin/fsp/fsp0fsp.c	2010-08-27 16:44:21.673058570 +0900
+@@ -658,15 +658,16 @@
+ 	ulint	offset)		/*!< in: page offset */
+ {
+ #ifndef DOXYGEN /* Doxygen gets confused of these */
+-# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+-		+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
+-#  error
+-# endif
++//# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET
++//		+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
++//#  error
++//# endif
+ # if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
+ 		+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
+ #  error
+ # endif
+ #endif /* !DOXYGEN */
++	ut_a(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE);
+ 	ut_ad(ut_is_2pow(zip_size));
+ 
+ 	if (!zip_size) {
+@@ -1465,12 +1466,12 @@
+ 							   mtr);
+ 		xdes_init(descr, mtr);
+ 
+-#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
+-# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
+-#endif
+-#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
+-# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
+-#endif
++//#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
++//# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
++//#endif
++//#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
++//# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
++//#endif
+ 
+ 		if (UNIV_UNLIKELY(init_xdes)) {
+ 
+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:43:11.951020997 +0900
++++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-08-27 16:44:21.682059132 +0900
+@@ -151,6 +151,8 @@
+ static ulong innobase_read_io_threads;
+ static ulong innobase_write_io_threads;
+ 
++static ulong innobase_page_size;
++
+ static my_bool innobase_thread_concurrency_timer_based;
+ static long long innobase_buffer_pool_size, innobase_log_file_size;
+ 
+@@ -2084,6 +2086,36 @@
+ 	}
+ #endif /* UNIV_DEBUG */
+ 
++	srv_page_size = 0;
++	srv_page_size_shift = 0;
++
++	if (innobase_page_size != (1 << 14)) {
++		uint n_shift;
++
++		fprintf(stderr,
++			"InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
++		for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
++			if (innobase_page_size == ((ulong)1 << n_shift)) {
++				srv_page_size_shift = n_shift;
++				srv_page_size = (1 << srv_page_size_shift);
++				fprintf(stderr,
++					"InnoDB: The universal page size of the database is set to %lu.\n",
++					srv_page_size);
++				break;
++			}
++		}
++	} else {
++		srv_page_size_shift = 14;
++		srv_page_size = (1 << srv_page_size_shift);
++	}
++
++	if (!srv_page_size_shift) {
++		fprintf(stderr,
++			"InnoDB: Error: %lu is not valid value for innodb_page_size.\n",
++			innobase_page_size);
++		goto error;
++	}
++
+ #ifndef MYSQL_SERVER
+ 	innodb_overwrite_relay_log_info = FALSE;
+ #endif
+@@ -7006,9 +7038,9 @@
+ 				| DICT_TF_COMPACT
+ 				| DICT_TF_FORMAT_ZIP
+ 				<< DICT_TF_FORMAT_SHIFT;
+-#if DICT_TF_ZSSIZE_MAX < 1
+-# error "DICT_TF_ZSSIZE_MAX < 1"
+-#endif
++//#if DICT_TF_ZSSIZE_MAX < 1
++//# error "DICT_TF_ZSSIZE_MAX < 1"
++//#endif
+ 		}
+ 	}
+ 
+@@ -11116,6 +11148,11 @@
+   "#### Attention: The checksum is not compatible for normal or disabled version! ####",
+   NULL, NULL, FALSE);
+ 
++static MYSQL_SYSVAR_ULONG(page_size, innobase_page_size,
++  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
++  "###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!",
++  NULL, NULL, (1 << 14), (1 << 12), (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
++
+ static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
+   PLUGIN_VAR_READONLY,
+   "The common part for InnoDB table spaces.",
+@@ -11602,6 +11639,7 @@
+   NULL, NULL, 0, 0, 1, 0);
+ 
+ static struct st_mysql_sys_var* innobase_system_variables[]= {
++  MYSQL_SYSVAR(page_size),
+   MYSQL_SYSVAR(additional_mem_pool_size),
+   MYSQL_SYSVAR(autoextend_increment),
+   MYSQL_SYSVAR(buffer_pool_size),
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:43:11.956017166 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:44:21.687100395 +0900
+@@ -45,5 +45,6 @@
+ {"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
+diff -ruN a/storage/innodb_plugin/include/buf0buddy.h b/storage/innodb_plugin/include/buf0buddy.h
+--- a/storage/innodb_plugin/include/buf0buddy.h	2010-08-27 16:13:11.077063445 +0900
++++ b/storage/innodb_plugin/include/buf0buddy.h	2010-08-27 16:44:21.689059215 +0900
+@@ -83,7 +83,7 @@
+ 
+ /** Statistics of the buddy system, indexed by block size.
+ Protected by buf_pool_mutex. */
+-extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
++extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
+ 
+ #ifndef UNIV_NONINL
+ # include "buf0buddy.ic"
+diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
+--- a/storage/innodb_plugin/include/buf0buf.h	2010-08-27 16:43:11.959021085 +0900
++++ b/storage/innodb_plugin/include/buf0buf.h	2010-08-27 16:44:21.691058408 +0900
+@@ -1452,11 +1452,11 @@
+ 	/* @{ */
+ 	UT_LIST_BASE_NODE_T(buf_page_t)	zip_clean;
+ 					/*!< unmodified compressed pages */
+-	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
++	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];
+ 					/*!< buddy free lists */
+-#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
+-# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
+-#endif
++//#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
++//# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
++//#endif
+ #if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
+ # error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
+ #endif
+diff -ruN a/storage/innodb_plugin/include/buf0types.h b/storage/innodb_plugin/include/buf0types.h
+--- a/storage/innodb_plugin/include/buf0types.h	2010-08-04 02:24:19.000000000 +0900
++++ b/storage/innodb_plugin/include/buf0types.h	2010-08-27 16:44:21.692071229 +0900
+@@ -70,6 +70,7 @@
+ 					buddy system; must be at least
+ 					sizeof(buf_page_t) */
+ #define BUF_BUDDY_SIZES		(UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
++#define BUF_BUDDY_SIZES_MAX	(UNIV_PAGE_SIZE_SHIFT_MAX - BUF_BUDDY_LOW_SHIFT)
+ 					/*!< number of buddy sizes */
+ 
+ /** twice the maximum block size of the buddy system;
+diff -ruN a/storage/innodb_plugin/include/mtr0log.ic b/storage/innodb_plugin/include/mtr0log.ic
+--- a/storage/innodb_plugin/include/mtr0log.ic	2010-08-27 16:38:38.273059844 +0900
++++ b/storage/innodb_plugin/include/mtr0log.ic	2010-08-27 16:44:21.693073476 +0900
+@@ -203,7 +203,7 @@
+ 	system tablespace */
+ 	if ((space == TRX_SYS_SPACE
+ 	     || (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
+-	    && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
++	    && offset >= (ulint)FSP_EXTENT_SIZE && offset < 3 * (ulint)FSP_EXTENT_SIZE) {
+ 		if (trx_doublewrite_buf_is_being_created) {
+ 			/* Do nothing: we only come to this branch in an
+ 			InnoDB database creation. We do not redo log
+diff -ruN a/storage/innodb_plugin/include/page0types.h b/storage/innodb_plugin/include/page0types.h
+--- a/storage/innodb_plugin/include/page0types.h	2010-08-04 02:24:19.000000000 +0900
++++ b/storage/innodb_plugin/include/page0types.h	2010-08-27 16:44:21.695063547 +0900
+@@ -56,8 +56,9 @@
+ 
+ /** Number of supported compressed page sizes */
+ #define PAGE_ZIP_NUM_SSIZE (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
+-#if PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)
+-# error "PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)"
++#define PAGE_ZIP_NUM_SSIZE_MAX (UNIV_PAGE_SIZE_SHIFT_MAX - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
++#if PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)
++# error "PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)"
+ #endif
+ 
+ /** Compressed page descriptor */
+@@ -98,7 +99,7 @@
+ typedef struct page_zip_stat_struct page_zip_stat_t;
+ 
+ /** Statistics on compression, indexed by page_zip_des_struct::ssize - 1 */
+-extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
++extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
+ 
+ /**********************************************************************//**
+ Write the "deleted" flag of a record on a compressed page.  The flag must
+diff -ruN a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/include/trx0sys.h
+--- a/storage/innodb_plugin/include/trx0sys.h	2010-08-27 16:38:38.277021207 +0900
++++ b/storage/innodb_plugin/include/trx0sys.h	2010-08-27 16:44:21.696063957 +0900
+@@ -515,9 +515,9 @@
+ /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
+ #define TRX_SYS_MYSQL_LOG_MAGIC_N	873422344
+ 
+-#if UNIV_PAGE_SIZE < 4096
+-# error "UNIV_PAGE_SIZE < 4096"
+-#endif
++//#if UNIV_PAGE_SIZE < 4096
++//# error "UNIV_PAGE_SIZE < 4096"
++//#endif
+ /** The offset of the MySQL replication info in the trx system header;
+ this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
+ #define TRX_SYS_MYSQL_MASTER_LOG_INFO	(UNIV_PAGE_SIZE - 2000)
+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 @@
+ */
+ 
+ /* The 2-logarithm of UNIV_PAGE_SIZE: */
+-#define UNIV_PAGE_SIZE_SHIFT	14
++/* #define UNIV_PAGE_SIZE_SHIFT	14 */
++#define UNIV_PAGE_SIZE_SHIFT_MAX	14
++#define UNIV_PAGE_SIZE_SHIFT	srv_page_size_shift
+ /* The universal page size of the database */
+-#define UNIV_PAGE_SIZE		(1 << UNIV_PAGE_SIZE_SHIFT)
++/* #define UNIV_PAGE_SIZE		(1 << UNIV_PAGE_SIZE_SHIFT) */
++#define UNIV_PAGE_SIZE		srv_page_size
++#define UNIV_PAGE_SIZE_MAX	(1 << UNIV_PAGE_SIZE_SHIFT_MAX)
+ 
+ /* Maximum number of parallel threads in a parallelized operation */
+ #define UNIV_MAX_PARALLELISM	32
+@@ -384,7 +388,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. */
+ 
+-#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
++#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_MAX)
+ 
+ /* Some macros to improve branch prediction and reduce cache misses */
+ #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
+@@ -487,4 +491,6 @@
+ 	UNIV_MEM_ALLOC(addr, size);			\
+ } while (0)
+ 
++extern ulint	srv_page_size_shift;
++extern ulint	srv_page_size;
+ #endif
+diff -ruN a/storage/innodb_plugin/log/log0log.c b/storage/innodb_plugin/log/log0log.c
+--- a/storage/innodb_plugin/log/log0log.c	2010-08-27 16:27:30.229021112 +0900
++++ b/storage/innodb_plugin/log/log0log.c	2010-08-27 16:44:21.701058790 +0900
+@@ -591,7 +591,9 @@
+ 
+ 	offset = (gr_lsn_size_offset + difference) % group_size;
+ 
++	if (sizeof(ulint) == 4) {
+ 	ut_a(offset < (((ib_int64_t) 1) << 32)); /* offset must be < 4 GB */
++	}
+ 
+ 	/* fprintf(stderr,
+ 	"Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
+@@ -1791,6 +1793,7 @@
+ 	mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, log_sys->buf_size);
+ 
+ #ifdef UNIV_LOG_ARCHIVE
++#error "UNIV_LOG_ARCHIVE could not be enabled"
+ 	if (log_sys->archiving_state == LOG_ARCH_OFF) {
+ 		archived_lsn = IB_ULONGLONG_MAX;
+ 	} else {
+@@ -1804,7 +1807,9 @@
+ 
+ 	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
+ #else /* UNIV_LOG_ARCHIVE */
+-	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
++	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN,
++			(ib_uint64_t)log_group_calc_lsn_offset(
++				log_sys->next_checkpoint_lsn, group));
+ #endif /* UNIV_LOG_ARCHIVE */
+ 
+ 	for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
+diff -ruN a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c
+--- a/storage/innodb_plugin/log/log0recv.c	2010-08-27 16:23:31.034058951 +0900
++++ b/storage/innodb_plugin/log/log0recv.c	2010-08-27 16:44:21.705059074 +0900
+@@ -702,8 +702,22 @@
+ 
+ 			group->lsn = mach_read_ull(
+ 				buf + LOG_CHECKPOINT_LSN);
++
++#ifdef UNIV_LOG_ARCHIVE
++#error "UNIV_LOG_ARCHIVE could not be enabled"
++#endif
++			{
++			ib_uint64_t tmp_lsn_offset = mach_read_ull(
++					buf + LOG_CHECKPOINT_ARCHIVED_LSN);
++				if (sizeof(ulint) != 4
++				    && tmp_lsn_offset != IB_ULONGLONG_MAX) {
++					group->lsn_offset = (ulint) tmp_lsn_offset;
++				} else {
+ 			group->lsn_offset = mach_read_from_4(
+ 				buf + LOG_CHECKPOINT_OFFSET);
++				}
++			}
++
+ 			checkpoint_no = mach_read_ull(
+ 				buf + LOG_CHECKPOINT_NO);
+ 
+diff -ruN a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c
+--- a/storage/innodb_plugin/page/page0zip.c	2010-08-27 16:40:36.584058988 +0900
++++ b/storage/innodb_plugin/page/page0zip.c	2010-08-27 16:44:21.709058243 +0900
+@@ -49,7 +49,7 @@
+ 
+ #ifndef UNIV_HOTBACKUP
+ /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
+-UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
++UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
+ #endif /* !UNIV_HOTBACKUP */
+ 
+ /* Please refer to ../include/page0zip.ic for a description of the
+diff -ruN a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c
+--- a/storage/innodb_plugin/row/row0merge.c	2010-08-27 16:40:36.591058306 +0900
++++ b/storage/innodb_plugin/row/row0merge.c	2010-08-27 16:44:21.713021156 +0900
+@@ -92,7 +92,7 @@
+ row_merge_block_t.  Thus, it must be able to hold one merge record,
+ whose maximum size is the same as the minimum size of
+ row_merge_block_t. */
+-typedef byte	mrec_buf_t[UNIV_PAGE_SIZE];
++typedef byte	mrec_buf_t[UNIV_PAGE_SIZE_MAX];
+ 
+ /** @brief Merge record in row_merge_block_t.
+ 
+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:43:11.968059077 +0900
++++ b/storage/innodb_plugin/srv/srv0srv.c	2010-08-27 16:44:21.716988122 +0900
+@@ -217,6 +217,10 @@
+ UNIV_INTERN ulint	srv_n_read_io_threads	= ULINT_MAX;
+ UNIV_INTERN ulint	srv_n_write_io_threads	= ULINT_MAX;
+ 
++/* The universal page size of the database */
++UNIV_INTERN ulint	srv_page_size_shift	= 0;
++UNIV_INTERN ulint	srv_page_size		= 0;
++
+ /* User settable value of the number of pages that must be present
+ in the buffer cache and accessed sequentially for InnoDB to trigger a
+ readahead request. */
+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
+@@ -1486,10 +1486,12 @@
+ 	}
+ #endif /* UNIV_LOG_ARCHIVE */
+ 
+-	if (srv_n_log_files * srv_log_file_size >= 262144) {
++	if (sizeof(ulint) == 4
++	    && srv_n_log_files * srv_log_file_size
++	       >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
+ 		fprintf(stderr,
+ 			"InnoDB: Error: combined size of log files"
+-			" must be < 4 GB\n");
++			" must be < 4 GB on 32-bit systems\n");
+ 
+ 		return(DB_ERROR);
+ 	}
+@@ -1498,7 +1500,7 @@
+ 
+ 	for (i = 0; i < srv_n_data_files; i++) {
+ #ifndef __WIN__
+-		if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
++		if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
+ 			fprintf(stderr,
+ 				"InnoDB: Error: file size must be < 4 GB"
+ 				" with this MySQL binary\n"
diff --git a/mysql-innodb_fix_misc.patch b/mysql-innodb_fix_misc.patch
new file mode 100644
index 0000000..1c78be2
--- /dev/null
+++ b/mysql-innodb_fix_misc.patch
@@ -0,0 +1,137 @@
+# name       : innodb_fix_misc.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/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
+@@ -11735,7 +11735,7 @@
+   &innobase_storage_engine,
+   innobase_hton_name,
+   "Innobase Oy",
+-  "Supports transactions, row-level locking, and foreign keys",
++  "Percona-XtraDB, Supports transactions, row-level locking, and foreign keys",
+   PLUGIN_LICENSE_GPL,
+   innobase_init, /* Plugin Init */
+   NULL, /* Plugin Deinit */
+diff -ruN a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
+--- a/storage/innodb_plugin/include/univ.i	2010-04-30 16:37:05.000000000 +0900
++++ 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	13
+ 
++#ifndef PERCONA_INNODB_VERSION
++#define PERCONA_INNODB_VERSION 12.1
++#endif
++
++
+ /* The following is the InnoDB version as shown in
+ SELECT plugin_version FROM information_schema.plugins;
+ calculated in make_version_string() in sql/sql_show.cc like this:
+@@ -58,13 +63,15 @@
+ 	(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
+ 
+ /* auxiliary macros to help creating the version as string */
+-#define __INNODB_VERSION(a, b, c)	(#a "." #b "." #c)
+-#define _INNODB_VERSION(a, b, c)	__INNODB_VERSION(a, b, c)
++#define __INNODB_VERSION(a, b, c, d)   (#a "." #b "." #c "-" #d)
++#define _INNODB_VERSION(a, b, c, d)    __INNODB_VERSION(a, b, c, d)
++
+ 
+ #define INNODB_VERSION_STR			\
+ 	_INNODB_VERSION(INNODB_VERSION_MAJOR,	\
+ 			INNODB_VERSION_MINOR,	\
+-			INNODB_VERSION_BUGFIX)
++			INNODB_VERSION_BUGFIX,  \
++			PERCONA_INNODB_VERSION)
+ 
+ #define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
+ 
+diff -ruN a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
+--- a/storage/innodb_plugin/row/row0mysql.c	2010-07-20 16:33:04.097866666 +0900
++++ b/storage/innodb_plugin/row/row0mysql.c	2010-07-20 16:33:53.995828763 +0900
+@@ -1134,6 +1134,13 @@
+ 
+ 	thr = que_fork_get_first_thr(prebuilt->ins_graph);
+ 
++	if (!prebuilt->mysql_has_locked) {
++		fprintf(stderr, "InnoDB: Error: row_insert_for_mysql is called without ha_innobase::external_lock()\n");
++		if (trx->mysql_thd != NULL) {
++			innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
++		}
++	}
++
+ 	if (prebuilt->sql_stat_start) {
+ 		node->state = INS_NODE_SET_IX_LOCK;
+ 		prebuilt->sql_stat_start = FALSE;
+diff -ruN a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c
+--- a/storage/innodb_plugin/row/row0sel.c	2010-07-20 16:33:04.204866103 +0900
++++ b/storage/innodb_plugin/row/row0sel.c	2010-07-20 16:33:53.998864025 +0900
+@@ -3362,6 +3362,7 @@
+ 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
+ 	ulint*		offsets				= offsets_;
+ 	ibool		table_lock_waited		= FALSE;
++	ibool		problematic_use = FALSE;
+ 
+ 	rec_offs_init(offsets_);
+ 
+@@ -3728,6 +3729,15 @@
+ 
+ 	/* Do some start-of-statement preparations */
+ 
++	if (!prebuilt->mysql_has_locked) {
++		fprintf(stderr, "InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock()\n");
++		if (trx->mysql_thd != NULL) {
++			innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
++		}
++		problematic_use = TRUE;
++	}
++retry_check:
++	
+ 	if (!prebuilt->sql_stat_start) {
+ 		/* No need to set an intention lock or assign a read view */
+ 
+@@ -3738,6 +3748,14 @@
+ 			      " perform a consistent read\n"
+ 			      "InnoDB: but the read view is not assigned!\n",
+ 			      stderr);
++			if (problematic_use) {
++				fprintf(stderr, "InnoDB: It may be caused by calling "
++						"without ha_innobase::external_lock()\n"
++						"InnoDB: For the first-aid, avoiding the crash. "
++						"But it should be fixed ASAP.\n");
++				prebuilt->sql_stat_start = TRUE;
++				goto retry_check;
++			}
+ 			trx_print(stderr, trx, 600);
+ 			fputc('\n', stderr);
+ 			ut_error;
+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
+@@ -1967,7 +1967,7 @@
+ 	if (srv_print_verbose_log) {
+ 		ut_print_timestamp(stderr);
+ 		fprintf(stderr,
+-			" InnoDB Plugin %s started; "
++			" Percona XtraDB (http://www.percona.com) %s started; "
+ 			"log sequence number %llu\n",
+ 			INNODB_VERSION_STR, srv_start_lsn);
+ 	}
+diff -ruN a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c
+--- a/storage/innodb_plugin/trx/trx0purge.c	2010-07-21 14:52:46.538653893 +0900
++++ b/storage/innodb_plugin/trx/trx0purge.c	2010-07-21 14:57:46.505530034 +0900
+@@ -1144,8 +1144,7 @@
+ 	/* If we cannot advance the 'purge view' because of an old
+ 	'consistent read view', then the DML statements cannot be delayed.
+ 	Also, srv_max_purge_lag <= 0 means 'infinity'. */
+-	if (srv_max_purge_lag > 0
+-	    && !UT_LIST_GET_LAST(trx_sys->view_list)) {
++	if (srv_max_purge_lag > 0) {
+ 		float	ratio = (float) trx_sys->rseg_history_len
+ 			/ srv_max_purge_lag;
+ 		if (ratio > ULINT_MAX / 10000) {
diff --git a/mysql-innodb_lru_dump_restore.patch b/mysql-innodb_lru_dump_restore.patch
new file mode 100644
index 0000000..f2222b4
--- /dev/null
+++ b/mysql-innodb_lru_dump_restore.patch
@@ -0,0 +1,698 @@
+# name       : innodb_lru_dump_restore.patch
+# introduced : 11 or before
+# maintainer : Yasufumi
+#
+#!!! 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/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
+@@ -2122,6 +2122,278 @@
+ 	memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
+ }
+ 
++/********************************************************************//**
++Dump the LRU page list to the specific file. */
++#define LRU_DUMP_FILE "ib_lru_dump"
++
++UNIV_INTERN
++ibool
++buf_LRU_file_dump(void)
++/*===================*/
++{
++	os_file_t	dump_file = -1;
++	ibool		success;
++	byte*		buffer_base = NULL;
++	byte*		buffer = NULL;
++	buf_page_t*	bpage;
++	ulint		buffers;
++	ulint		offset;
++	ibool		ret = FALSE;
++	ulint		i;
++
++	for (i = 0; i < srv_n_data_files; i++) {
++		if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
++			fprintf(stderr,
++				" InnoDB: The name '%s' seems to be used for"
++				" innodb_data_file_path. Dumping LRU list is not"
++				" done for safeness.\n", LRU_DUMP_FILE);
++			goto end;
++		}
++	}
++
++	buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
++	buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
++	if (!buffer) {
++		fprintf(stderr,
++			" InnoDB: cannot allocate buffer.\n");
++		goto end;
++	}
++
++	dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
++				OS_FILE_NORMAL, OS_DATA_FILE, &success);
++	if (!success) {
++		os_file_get_last_error(TRUE);
++		fprintf(stderr,
++			" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
++		goto end;
++	}
++
++	mutex_enter(&LRU_list_mutex);
++	bpage = UT_LIST_GET_LAST(buf_pool->LRU);
++
++	buffers = offset = 0;
++	while (bpage != NULL) {
++		if (offset == 0) {
++			memset(buffer, 0, UNIV_PAGE_SIZE);
++		}
++
++		mach_write_to_4(buffer + offset * 4, bpage->space);
++		offset++;
++		mach_write_to_4(buffer + offset * 4, bpage->offset);
++		offset++;
++
++		if (offset == UNIV_PAGE_SIZE/4) {
++			success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
++					(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
++					(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
++					UNIV_PAGE_SIZE);
++			if (!success) {
++				mutex_exit(&LRU_list_mutex);
++				fprintf(stderr,
++					" InnoDB: cannot write page %lu of %s\n",
++					buffers, LRU_DUMP_FILE);
++				goto end;
++			}
++			buffers++;
++			offset = 0;
++		}
++
++		bpage = UT_LIST_GET_PREV(LRU, bpage);
++	}
++	mutex_exit(&LRU_list_mutex);
++
++	if (offset == 0) {
++		memset(buffer, 0, UNIV_PAGE_SIZE);
++	}
++
++	mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
++	offset++;
++	mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
++	offset++;
++
++	success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
++			(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
++			(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
++			UNIV_PAGE_SIZE);
++	if (!success) {
++		goto end;
++	}
++
++	ret = TRUE;
++end:
++	if (dump_file != -1)
++		os_file_close(dump_file);
++	if (buffer_base)
++		ut_free(buffer_base);
++
++	return(ret);
++}
++
++typedef struct {
++	ib_uint32_t space_id;
++	ib_uint32_t page_no;
++} dump_record_t;
++
++static int dump_record_cmp(const void *a, const void *b)
++{
++	const dump_record_t *rec1 = (dump_record_t *) a;
++	const dump_record_t *rec2 = (dump_record_t *) b;
++
++	if (rec1->space_id < rec2->space_id)
++		return -1;
++	if (rec1->space_id > rec2->space_id)
++		return 1;
++	if (rec1->page_no < rec2->page_no)
++		return -1;
++	return rec1->page_no > rec2->page_no;
++}
++
++/********************************************************************//**
++Read the pages based on the specific file.*/
++UNIV_INTERN
++ibool
++buf_LRU_file_restore(void)
++/*======================*/
++{
++	os_file_t	dump_file = -1;
++	ibool		success;
++	byte*		buffer_base = NULL;
++	byte*		buffer = NULL;
++	ulint		buffers;
++	ulint		offset;
++	ulint		reads = 0;
++	ulint		req = 0;
++	ibool		terminated = FALSE;
++	ibool		ret = FALSE;
++	dump_record_t*	records;
++	ulint		size;
++	ulint		size_high;
++	ulint		length;
++
++	dump_file = os_file_create_simple_no_error_handling(
++		LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
++	if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
++		os_file_get_last_error(TRUE);
++		fprintf(stderr,
++			" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
++		goto end;
++	}
++	if (size == 0 || size_high > 0 || size % 8) {
++		fprintf(stderr, " InnoDB: broken LRU dump file\n");
++		goto end;
++	}
++	buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
++	buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
++	records = ut_malloc(size);
++	if (!buffer || !records) {
++		fprintf(stderr,
++			" InnoDB: cannot allocate buffer.\n");
++		goto end;
++	}
++
++	buffers = 0;
++	length = 0;
++	while (!terminated) {
++		success = os_file_read(dump_file, buffer,
++				(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
++				(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
++				UNIV_PAGE_SIZE);
++		if (!success) {
++			fprintf(stderr,
++				" InnoDB: cannot read page %lu of %s,"
++				" or meet unexpected terminal.\n",
++				buffers, LRU_DUMP_FILE);
++			goto end;
++		}
++
++		for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
++			ulint	space_id;
++			ulint	page_no;
++
++			space_id = mach_read_from_4(buffer + offset * 4);
++			page_no = mach_read_from_4(buffer + (offset + 1) * 4);
++			if (space_id == 0xFFFFFFFFUL
++			    || page_no == 0xFFFFFFFFUL) {
++				terminated = TRUE;
++				break;
++			}
++
++			records[length].space_id = space_id;
++			records[length].page_no = page_no;
++			length++;
++			if (length * 8 >= size) {
++				fprintf(stderr,
++					" InnoDB: could not find the "
++					"end-of-file marker after reading "
++					"the expected %lu bytes from the "
++					"LRU dump file.\n"
++					" InnoDB: this could be caused by a "
++					"broken or incomplete file.\n"
++					" InnoDB: trying to process what has "
++					"been read so far.\n",
++					size);
++				terminated= TRUE;
++				break;
++			}
++		}
++		buffers++;
++	}
++
++	qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
++
++	for (offset = 0; offset < length; offset++) {
++		ulint		space_id;
++		ulint		page_no;
++		ulint		zip_size;
++		ulint		err;
++		ib_int64_t	tablespace_version;
++
++		space_id = records[offset].space_id;
++		page_no = records[offset].page_no;
++
++		if (offset % 16 == 15) {
++			os_aio_simulated_wake_handler_threads();
++			buf_flush_free_margin(FALSE);
++		}
++
++		zip_size = fil_space_get_zip_size(space_id);
++		if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
++			continue;
++		}
++
++		if (fil_area_is_exist(space_id, zip_size, page_no, 0,
++				      zip_size ? zip_size : UNIV_PAGE_SIZE)) {
++
++			tablespace_version = fil_space_get_version(space_id);
++
++			req++;
++			reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
++						   | OS_AIO_SIMULATED_WAKE_LATER,
++						   space_id, zip_size, TRUE,
++						   tablespace_version, page_no, NULL);
++			buf_LRU_stat_inc_io();
++		}
++	}
++
++	os_aio_simulated_wake_handler_threads();
++	buf_flush_free_margin(FALSE);
++
++	ut_print_timestamp(stderr);
++	fprintf(stderr,
++		" InnoDB: reading pages based on the dumped LRU list was done."
++		" (requested: %lu, read: %lu)\n", req, reads);
++	ret = TRUE;
++end:
++	if (dump_file != -1)
++		os_file_close(dump_file);
++	if (buffer_base)
++		ut_free(buffer_base);
++	if (records)
++		ut_free(records);
++
++	return(ret);
++}
++
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
+ /**********************************************************************//**
+ Validates the LRU list.
+diff -ruN a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c
+--- a/storage/innodb_plugin/buf/buf0rea.c	2010-08-27 16:32:40.293411717 +0900
++++ b/storage/innodb_plugin/buf/buf0rea.c	2010-08-27 16:34:33.863409016 +0900
+@@ -56,7 +56,7 @@
+ which case it is never read into the pool, or if the tablespace does
+ not exist or is being dropped 
+ @return 1 if read request is issued. 0 if it is not */
+-static
++UNIV_INTERN
+ ulint
+ buf_read_page_low(
+ /*==============*/
+diff -ruN a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
+--- a/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:32:40.298411400 +0900
++++ b/storage/innodb_plugin/fil/fil0fil.c	2010-08-27 16:34:33.868058362 +0900
+@@ -4869,6 +4869,78 @@
+ 	return(DB_SUCCESS);
+ }
+ 
++/********************************************************************//**
++Confirm whether the parameters are valid or not */
++UNIV_INTERN
++ibool
++fil_area_is_exist(
++/*==============*/
++	ulint	space_id,	/*!< in: space id */
++	ulint	zip_size,	/*!< in: compressed page size in bytes;
++				0 for uncompressed pages */
++	ulint	block_offset,	/*!< in: offset in number of blocks */
++	ulint	byte_offset,	/*!< in: remainder of offset in bytes; in
++				aio this must be divisible by the OS block
++				size */
++	ulint	len)		/*!< in: how many bytes to read or write; this
++				must not cross a file boundary; in aio this
++				must be a block size multiple */
++{
++	fil_space_t*	space;
++	fil_node_t*	node;
++
++	/* Reserve the fil_system mutex and make sure that we can open at
++	least one file while holding it, if the file is not already open */
++
++	fil_mutex_enter_and_prepare_for_io(space_id);
++
++	space = fil_space_get_by_id(space_id);
++
++	if (!space) {
++		mutex_exit(&fil_system->mutex);
++		return(FALSE);
++	}
++
++	node = UT_LIST_GET_FIRST(space->chain);
++
++	for (;;) {
++		if (UNIV_UNLIKELY(node == NULL)) {
++			mutex_exit(&fil_system->mutex);
++			return(FALSE);
++		}
++
++		if (space->id != 0 && node->size == 0) {
++			/* We do not know the size of a single-table tablespace
++			before we open the file */
++
++			break;
++		}
++
++		if (node->size > block_offset) {
++			/* Found! */
++			break;
++		} else {
++			block_offset -= node->size;
++			node = UT_LIST_GET_NEXT(chain, node);
++		}
++	}
++
++	/* Open file if closed */
++	fil_node_prepare_for_io(node, fil_system, space);
++	fil_node_complete_io(node, fil_system, OS_FILE_READ);
++
++	/* Check that at least the start offset is within the bounds of a
++	single-table tablespace */
++	if (UNIV_UNLIKELY(node->size <= block_offset)
++	    && space->id != 0 && space->purpose == FIL_TABLESPACE) {
++		mutex_exit(&fil_system->mutex);
++		return(FALSE);
++	}
++
++	mutex_exit(&fil_system->mutex);
++	return(TRUE);
++}
++
+ #ifndef UNIV_HOTBACKUP
+ /**********************************************************************//**
+ Waits for an aio operation to complete. This function is used to write the
+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
+@@ -11471,6 +11471,12 @@
+   "Limit the allocated memory for dictionary cache. (0: unlimited)",
+   NULL, NULL, 0, 0, LONG_MAX, 0);
+ 
++static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump,
++  PLUGIN_VAR_RQCMDARG,
++  "Time in seconds between automatic buffer pool dumps. "
++  "0 (the default) disables automatic dumps.",
++  NULL, NULL, 0, 0, UINT_MAX32, 0);
++
+ static struct st_mysql_sys_var* innobase_system_variables[]= {
+   MYSQL_SYSVAR(additional_mem_pool_size),
+   MYSQL_SYSVAR(autoextend_increment),
+@@ -11553,6 +11559,7 @@
+ #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+   MYSQL_SYSVAR(read_ahead_threshold),
+   MYSQL_SYSVAR(io_capacity),
++  MYSQL_SYSVAR(auto_lru_dump),
+   MYSQL_SYSVAR(use_purge_thread),
+   NULL
+ };
+diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
+--- a/storage/innodb_plugin/handler/i_s.cc	2010-08-27 16:29:12.540979608 +0900
++++ b/storage/innodb_plugin/handler/i_s.cc	2010-08-27 16:34:33.873058189 +0900
+@@ -46,6 +46,7 @@
+ #include "trx0rseg.h" /* for trx_rseg_struct */
+ #include "trx0sys.h" /* for trx_sys */
+ #include "dict0dict.h" /* for dict_sys */
++#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
+ }
+ 
+ static const char plugin_author[] = "Innobase Oy";
+@@ -3041,6 +3042,36 @@
+ 			"Hello!");
+ 		goto end_func;
+ 	}
++	else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
++		ut_print_timestamp(stderr);
++		fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
++				" was detected.\n");
++
++		if (buf_LRU_file_dump()) {
++			field_store_string(i_s_table->field[0],
++				"XTRA_LRU_DUMP was succeeded.");
++		} else {
++			field_store_string(i_s_table->field[0],
++				"XTRA_LRU_DUMP was failed.");
++		}
++
++		goto end_func;
++	}
++	else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
++		ut_print_timestamp(stderr);
++		fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
++				" was detected.\n");
++
++		if (buf_LRU_file_restore()) {
++			field_store_string(i_s_table->field[0],
++				"XTRA_LRU_RESTORE was succeeded.");
++		} else {
++			field_store_string(i_s_table->field[0],
++				"XTRA_LRU_RESTORE was failed.");
++		}
++
++		goto end_func;
++	}
+ 
+ 	field_store_string(i_s_table->field[0],
+ 		"Undefined XTRA_* command.");
+diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
+--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:32:40.313021803 +0900
++++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-08-27 16:34:33.871059345 +0900
+@@ -41,5 +41,6 @@
+ {"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
++{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
+ {NULL, NULL, NULL, NULL}
+ };
+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 @@
+ void
+ buf_LRU_stat_update(void);
+ /*=====================*/
++/********************************************************************//**
++Dump the LRU page list to the specific file. */
++UNIV_INTERN
++ibool
++buf_LRU_file_dump(void);
++/*===================*/
++/********************************************************************//**
++Read the pages based on the specific file.*/
++UNIV_INTERN
++ibool
++buf_LRU_file_restore(void);
++/*======================*/
+ 
+ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
+ /**********************************************************************//**
+diff -ruN a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
+--- a/storage/innodb_plugin/include/buf0rea.h	2010-08-27 16:32:40.314021595 +0900
++++ b/storage/innodb_plugin/include/buf0rea.h	2010-08-27 16:34:33.877059445 +0900
+@@ -31,6 +31,37 @@
+ #include "buf0types.h"
+ 
+ /********************************************************************//**
++Low-level function which reads a page asynchronously from a file to the
++buffer buf_pool if it is not already there, in which case does nothing.
++Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
++flag is cleared and the x-lock released by an i/o-handler thread.
++ at return 1 if a read request was queued, 0 if the page already resided
++in buf_pool, or if the page is in the doublewrite buffer blocks in
++which case it is never read into the pool, or if the tablespace does
++not exist or is being dropped 
++ at return 1 if read request is issued. 0 if it is not */
++UNIV_INTERN
++ulint
++buf_read_page_low(
++/*==============*/
++	ulint*	err,	/*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
++			trying to read from a non-existent tablespace, or a
++			tablespace which is just now being dropped */
++	ibool	sync,	/*!< in: TRUE if synchronous aio is desired */
++	ulint	mode,	/*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
++			ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
++			at read-ahead functions) */
++	ulint	space,	/*!< in: space id */
++	ulint	zip_size,/*!< in: compressed page size, or 0 */
++	ibool	unzip,	/*!< in: TRUE=request uncompressed page */
++	ib_int64_t tablespace_version, /*!< in: if the space memory object has
++			this timestamp different from what we are giving here,
++			treat the tablespace as dropped; this is a timestamp we
++			use to stop dangling page reads from a tablespace
++			which we have DISCARDed + IMPORTed back */
++	ulint	offset,	/*!< in: page number */
++	trx_t*	trx);
++/********************************************************************//**
+ High-level function which reads a page asynchronously from a file to the
+ buffer buf_pool if it is not already there. Sets the io_fix flag and sets
+ an exclusive lock on the buffer frame. The flag is cleared and the x-lock
+diff -ruN a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h
+--- a/storage/innodb_plugin/include/fil0fil.h	2010-08-27 16:32:40.315012507 +0900
++++ b/storage/innodb_plugin/include/fil0fil.h	2010-08-27 16:34:33.878063455 +0900
+@@ -643,6 +643,22 @@
+ 	void*	message,	/*!< in: message for aio handler if non-sync
+ 				aio used, else ignored */
+ 	trx_t*	trx);
++/********************************************************************//**
++Confirm whether the parameters are valid or not */
++UNIV_INTERN
++ibool
++fil_area_is_exist(
++/*==============*/
++	ulint	space_id,	/*!< in: space id */
++	ulint	zip_size,	/*!< in: compressed page size in bytes;
++				0 for uncompressed pages */
++	ulint	block_offset,	/*!< in: offset in number of blocks */
++	ulint	byte_offset,	/*!< in: remainder of offset in bytes; in
++				aio this must be divisible by the OS block
++				size */
++	ulint	len);		/*!< in: how many bytes to read or write; this
++				must not cross a file boundary; in aio this
++				must be a block size multiple */
+ /**********************************************************************//**
+ Waits for an aio operation to complete. This function is used to write the
+ handler for completed requests. The aio array of pending requests is divided
+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 @@
+ reading of a disk page */
+ extern ulint srv_buf_pool_reads;
+ 
++/** Time in seconds between automatic buffer pool dumps */
++extern uint srv_auto_lru_dump;
++
+ /** Status variables to be passed to MySQL */
+ typedef struct export_var_struct export_struc;
+ 
+@@ -602,6 +605,16 @@
+ /*=====================*/
+ 	void*	arg);	/*!< in: a dummy parameter required by
+ 			os_thread_create */
++/*********************************************************************//**
++A thread which restores the buffer pool from a dump file on startup and does
++periodic buffer pool dumps.
++ at return	a dummy parameter */
++UNIV_INTERN
++os_thread_ret_t
++srv_LRU_dump_restore_thread(
++/*====================*/
++	void*	arg);	/*!< in: a dummy parameter required by
++			os_thread_create */
+ /******************************************************************//**
+ Outputs to a file the output of the InnoDB Monitor.
+ @return FALSE if not all information printed
+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 @@
+ reading of a disk page */
+ UNIV_INTERN ulint srv_buf_pool_reads = 0;
+ 
++/** Time in seconds between automatic buffer pool dumps */
++UNIV_INTERN uint srv_auto_lru_dump = 0;
++
+ /* structure to pass status variables to MySQL */
+ UNIV_INTERN export_struc export_vars;
+ 
+@@ -2537,6 +2540,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. */
+ 
++	os_thread_exit(NULL);
++
++	OS_THREAD_DUMMY_RETURN;
++}
++
++/*********************************************************************//**
++A thread which restores the buffer pool from a dump file on startup and does
++periodic buffer pool dumps.
++ at return	a dummy parameter */
++UNIV_INTERN
++os_thread_ret_t
++srv_LRU_dump_restore_thread(
++/*====================*/
++	void*	arg __attribute__((unused)))
++			/*!< in: a dummy parameter required by
++			os_thread_create */
++{
++	uint	auto_lru_dump;
++	time_t	last_dump_time;
++	time_t	time_elapsed;
++
++#ifdef UNIV_DEBUG_THREAD_CREATION
++	fprintf(stderr, "LRU dump/restore thread starts, id %lu\n",
++		os_thread_pf(os_thread_get_curr_id()));
++#endif
++
++	if (srv_auto_lru_dump)
++		buf_LRU_file_restore();
++
++	last_dump_time = time(NULL);
++
++loop:
++	os_thread_sleep(5000000);
++
++	if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
++		goto exit_func;
++	}
++
++	time_elapsed = time(NULL) - last_dump_time;
++	auto_lru_dump = srv_auto_lru_dump;
++	if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
++		last_dump_time = time(NULL);
++		buf_LRU_file_dump();
++	}
++
++	goto loop;
++exit_func:
++	/* 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. */
++
+ 	os_thread_exit(NULL);
+ 
+ 	OS_THREAD_DUMMY_RETURN;
<Skipped 10963 lines>
================================================================

---- gitweb:

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




More information about the pld-cvs-commit mailing list