List:Commits« Previous MessageNext Message »
From:Joerg Bruehe Date:August 18 2011 9:39am
Subject:bzr push into mysql-5.5 branch (joerg.bruehe:3481 to 3499)
View as plain text  
 3499 Jimmy Yang	2011-08-16
      Add two tests for "innodb_large_prefix" and "innodb_force_load_corrupted" in
      sys_vars test suite.

    added:
      mysql-test/suite/sys_vars/r/innodb_force_load_corrupted_basic.result
      mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result
      mysql-test/suite/sys_vars/t/innodb_force_load_corrupted_basic.test
      mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test
    modified:
      mysql-test/suite/innodb/t/innodb_corrupt_bit.test
      mysql-test/suite/sys_vars/r/all_vars.result
      storage/innobase/buf/buf0buf.c
 3498 Jimmy Yang	2011-08-16
      Fix bug #11830883, SUPPORT "CORRUPTED" BIT FOR INNODB TABLES AND INDEXES.
      Also addressed issues in bug #11745133, where we could mark a table
      corrupted instead of crashing the server when found a corrupted buffer/page
      if the table created with innodb_file_per_table on.

    added:
      mysql-test/suite/innodb/r/innodb_corrupt_bit.result
      mysql-test/suite/innodb/t/innodb_corrupt_bit.test
    modified:
      include/my_base.h
      mysql-test/suite/sys_vars/r/all_vars.result
      mysys/my_handler_errors.h
      sql/handler.cc
      sql/share/errmsg-utf8.txt
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0lru.c
      storage/innobase/dict/dict0dict.c
      storage/innobase/dict/dict0load.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/include/buf0lru.h
      storage/innobase/include/db0err.h
      storage/innobase/include/dict0boot.h
      storage/innobase/include/dict0dict.h
      storage/innobase/include/dict0dict.ic
      storage/innobase/include/dict0mem.h
      storage/innobase/include/dict0types.h
      storage/innobase/include/srv0srv.h
      storage/innobase/pars/pars0opt.c
      storage/innobase/row/row0ins.c
      storage/innobase/row/row0merge.c
      storage/innobase/row/row0mysql.c
      storage/innobase/row/row0purge.c
      storage/innobase/row/row0sel.c
      storage/innobase/row/row0uins.c
      storage/innobase/row/row0umod.c
      storage/innobase/row/row0upd.c
      storage/innobase/ut/ut0ut.c
 3497 Sneha Modi	2011-08-16
      Fixing a few broken tests.

    modified:
      mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result
      mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result
      mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_basic.test
      mysql-test/suite/sys_vars/t/innodb_fast_shutdown_basic.test
      mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test
      mysql-test/suite/sys_vars/t/innodb_io_capacity_basic.test
      mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test
      mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test
 3496 Joerg Bruehe	2011-08-15 [merge]
      Null-merge,
      conflict on "configure.in" which is gone from 5.5.
      No change.

 3495 Joerg Bruehe	2011-08-15 [merge]
      Null merge for pushing.

 3494 Marko Mäkelä	2011-08-15 [merge]
      Merge mysql-5.1 to mysql-5.5. Add a test case.

    added:
      mysql-test/suite/innodb/r/innodb_bug59733.result
      mysql-test/suite/innodb/t/innodb_bug59733.test
    modified:
      storage/innobase/btr/btr0btr.c
      storage/innobase/btr/btr0cur.c
      storage/innobase/btr/btr0pcur.c
      storage/innobase/btr/btr0sea.c
      storage/innobase/dict/dict0crea.c
      storage/innobase/dict/dict0dict.c
      storage/innobase/ibuf/ibuf0ibuf.c
      storage/innobase/include/btr0btr.h
      storage/innobase/include/btr0btr.ic
      storage/innobase/include/sync0sync.h
      storage/innobase/sync/sync0sync.c
 3493 Georgi Kodinov	2011-08-12
      Bug #12777649: "OS THREAD ID" REMOVED 
      
      Pushed Calvin's patch.

    modified:
      sql/sql_class.cc
 3492 Georgi Kodinov	2011-08-12 [merge]
      merged the version bump. bumped the 5.5 version to 5.5.17

    modified:
      VERSION
 3491 Bjorn Munch	2011-08-12
      Small followup fix to WL 5710:
        Test mysql_plugin failed if version string ended in -mN

    modified:
      mysql-test/t/mysql_plugin.test
 3490 Dmitry Lenev	2011-08-11
      Fix for bug #12828477 - "MDL SUBSYSTEM CREATES BIG OVERHEAD 
      FOR CERTAIN QUERIES TO INFORMATION_SCHEMA".
      
      The problem was that metadata locking subsystem introduced
      too much overhead for queries to I_S which were processed by
      opening only .FRM or .TRG files and had to scanned a lot of
      tables (e.g. SELECT COUNT(*) FROM I_S.TRIGGERS was affected). 
      The same effect was not observed for similar queries which 
      performed full-blown table open in order to fill I_S table.
      
      The problem stemmed from the fact that in case when I_S 
      implementation opened only .FRM or .TRG file for each table 
      processed it didn't release metadata lock it has acquired on 
      the table after finishing its processing. As result, list
      of acquired metadata locks were growing until the end of 
      statement. Since acquisition of each new lock required 
      search in the list of already acquired locks performance
      degraded.
      
      The same effect is not observed when I_S implementation
      performs full-blown table open for each table being
      processed, as in the latter cases metadata lock on the
      table is released right after table processing.
      
      This fix addressed the problem by ensuring that I_S 
      implementation releases metadata lock after processing
      the table in both cases of full-blown table open and in 
      case when only .FRM or .TRG file is read.
     @ mysql-test/r/information_schema.result
        Added coverage for bug #12828477 - "MDL SUBSYSTEM CREATES BIG
        OVERHEAD FOR CERTAIN QUERIES TO INFORMATION_SCHEMA".
     @ mysql-test/t/information_schema.test
        Added coverage for bug #12828477 - "MDL SUBSYSTEM CREATES BIG
        OVERHEAD FOR CERTAIN QUERIES TO INFORMATION_SCHEMA".
     @ sql/sql_show.cc
        Changed fill_schema_table_from_frm() to release metadata lock
        it has acquired after processing the .FRM or .TRG file for
        table. 
        Without this step metadata locks acquired for each table 
        processed will be accumulated. In situation when a lot of 
        tables are processed by I_S query this will result in
        transaction with too many metadata locks. As result
        performance of acquisition of new lock will degrade.

    modified:
      mysql-test/r/information_schema.result
      mysql-test/t/information_schema.test
      sql/sql_show.cc
 3489 Tatjana Azundris Nuernberg	2011-08-11 [merge]
      auto-merge

    added:
      client/mysql_plugin.c
      mysql-test/include/daemon_example_bad_format.ini
      mysql-test/include/daemon_example_bad_soname.ini
      mysql-test/r/mysql_plugin.result
      mysql-test/suite/sys_vars/r/innodb_file_format_max_basic.result
      mysql-test/suite/sys_vars/r/innodb_rollback_segments_basic.result
      mysql-test/suite/sys_vars/r/innodb_stats_method_basic.result
      mysql-test/suite/sys_vars/t/innodb_file_format_max_basic.test
      mysql-test/suite/sys_vars/t/innodb_rollback_segments_basic.test
      mysql-test/suite/sys_vars/t/innodb_stats_method_basic.test
      mysql-test/t/mysql_plugin-master.opt
      mysql-test/t/mysql_plugin.test
      plugin/daemon_example/daemon_example.ini
    modified:
      client/CMakeLists.txt
      include/my_global.h
      mysql-test/include/plugin.defs
      mysql-test/mysql-test-run.pl
      mysql-test/suite/sys_vars/r/all_vars.result
      mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result
      mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test
      plugin/daemon_example/CMakeLists.txt
      storage/innobase/row/row0sel.c
      support-files/mysql.spec.sh
 3488 Tatjana Azundris Nuernberg	2011-08-11 [merge]
      auto-merge

 3487 Tatjana Azundris Nuernberg	2011-08-11 [merge]
      auto-merge

    modified:
      mysql-test/r/sp_trans.result
      mysql-test/t/sp_trans.test
      sql/sql_parse.cc
      sql/sql_yacc.yy
 3486 Marko Mäkelä	2011-08-08 [merge]
      Merge mysql-5.1 to mysql-5.5.

    modified:
      mysql-test/suite/innodb/r/innodb-zip.result
      mysql-test/suite/innodb/t/innodb-zip.test
      storage/innobase/handler/ha_innodb.cc
 3485 hery.ramilison@oracle.com	2011-08-06
      fixing BUG 11759958 - 52319: MYSQL RHEL5 RPMS DO NOT REQUIRE NET-TOOLS

    modified:
      support-files/mysql.spec.sh
 3484 Gleb Shchepa	2011-08-03
      backport from mysql-trunk
      
      BUG #11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG 
      
      The mysql_affected_rows() client call returns 3 instead of 2 on
      INSERT ... ON DUPLICATE KEY UPDATE query with a duplicated key value.
      
      The fix for the old bug #29692 was incomplete: unnecessary double
      increment of "touched" rows still happened.
      
      This bugfix removes:
      1) unneeded increment of "touched" rows and
      2) useless double resetting of auto-increment value.
     @ sql/sql_insert.cc
        write_record() function:
        Unneeded increment of "touched" rows and useless double resetting
        of auto-increment value has been removed.
     @ tests/mysql_client_test.c
        New test case.

    modified:
      sql/sql_insert.cc
      tests/mysql_client_test.c
 3483 Sergey Glukhov	2011-08-02 [merge]
      5.1 -> 5.5 merge
     @ mysql-test/r/sp.result
        5.1 -> 5.5 merge
     @ mysql-test/t/sp.test
        5.1 -> 5.5 merge
     @ sql/sql_base.cc
        5.1 -> 5.5 merge
     @ sql/sql_class.cc
        5.1 -> 5.5 merge
     @ sql/sql_class.h
        5.1 -> 5.5 merge
     @ sql/sql_insert.cc
        5.1 -> 5.5 merge
     @ sql/sql_lex.cc
        5.1 -> 5.5 merge
     @ sql/sql_lex.h
        5.1 -> 5.5 merge
     @ sql/sql_prepare.cc
        5.1 -> 5.5 merge
     @ sql/sql_select.cc
        5.1 -> 5.5 merge

    modified:
      mysql-test/r/sp.result
      mysql-test/t/sp.test
      sql/sql_base.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_prepare.cc
      sql/sql_select.cc
 3482 hery.ramilison@stripped	2011-07-28
      Merge from mysql-5.5.15-release

 3481 Sven Sandberg	2011-07-27 [merge]
      Null merge

=== modified file 'VERSION'
--- a/VERSION	2011-07-13 17:35:34 +0000
+++ b/VERSION	2011-08-12 11:25:36 +0000
@@ -1,4 +1,4 @@
 MYSQL_VERSION_MAJOR=5
 MYSQL_VERSION_MINOR=5
-MYSQL_VERSION_PATCH=16
+MYSQL_VERSION_PATCH=17
 MYSQL_VERSION_EXTRA=

=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt	2011-06-30 15:46:53 +0000
+++ b/client/CMakeLists.txt	2011-07-19 14:17:58 +0000
@@ -54,6 +54,9 @@ ADD_DEPENDENCIES(mysql_upgrade GenFixPri
 MYSQL_ADD_EXECUTABLE(mysqlshow mysqlshow.c)
 TARGET_LINK_LIBRARIES(mysqlshow mysqlclient)
 
+MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c)
+TARGET_LINK_LIBRARIES(mysql_plugin mysqlclient)
+
 MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc)
 TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient)
 
@@ -69,7 +72,7 @@ IF(WIN32)
   MYSQL_ADD_EXECUTABLE(echo echo.c)
 ENDIF(WIN32)
 
-SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap 
+SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin 
 PROPERTIES HAS_CXX TRUE)
 
 ADD_DEFINITIONS(-DHAVE_DLOPEN)

=== added file 'client/mysql_plugin.c'
--- a/client/mysql_plugin.c	1970-01-01 00:00:00 +0000
+++ b/client/mysql_plugin.c	2011-08-09 12:58:18 +0000
@@ -0,0 +1,1192 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <m_string.h>
+#include <mysql.h>
+#include <my_getopt.h>
+#include <my_dir.h>
+#include <my_global.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#define SHOW_VERSION "1.0.0"
+#define PRINT_VERSION do { printf("%s  Ver %s Distrib %s\n",    \
+                        my_progname, SHOW_VERSION, MYSQL_SERVER_VERSION);    \
+                      } while(0)
+
+/* Global variables. */
+static uint my_end_arg= 0;
+static uint opt_verbose=0;
+static uint opt_no_defaults= 0;
+static uint opt_print_defaults= 0;
+static char *opt_datadir=0, *opt_basedir=0,
+            *opt_plugin_dir=0, *opt_plugin_ini=0,
+            *opt_mysqld=0, *opt_my_print_defaults=0;
+static char bootstrap[FN_REFLEN];
+
+
+/* plugin struct */
+struct st_plugin
+{
+  const char *name;           /* plugin name */
+  const char *so_name;        /* plugin so (library) name */
+  const char *components[16]; /* components to load */
+} plugin_data;
+
+
+/* Options */
+static struct my_option my_long_options[] =
+{
+  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+    0, 0, 0, 0, 0, 0},
+  {"basedir", 'b', "The basedir for the server.",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"datadir", 'd', "The datadir for the server.",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"plugin-dir", 'p', "The plugin dir for the server.",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"plugin-ini", 'i', "Read plugin information from configuration file "
+   "specified instead of from <plugin-dir>/<plugin_name>.ini.",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"no-defaults", 'n', "Do not read values from configuration file.",
+    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"print-defaults", 'P', "Show default values from configuration file.",
+    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"mysqld", 'm', "Path to mysqld executable. Example: /sbin/temp1/mysql/bin",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"my-print-defaults", 'f', "Path to my_print_defaults executable. "
+   "Example: /source/temp11/extra",
+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"verbose", 'v',
+    "More verbose output; you can use this multiple times to get even more "
+    "verbose output.",
+    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+    NO_ARG, 0, 0, 0, 0, 0, 0},
+  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+/* Methods */
+static int process_options(int argc, char *argv[], char *operation);
+static int check_access();
+static int find_tool(const char *tool_name, char *tool_path);
+static int find_plugin(char *tp_path);
+static int build_bootstrap_file(char *operation, char *bootstrap);
+static int dump_bootstrap_file(char *bootstrap_file);
+static int bootstrap_server(char *server_path, char *bootstrap_file);
+
+
+int main(int argc,char *argv[])
+{
+  int error= 0;
+  char tp_path[FN_REFLEN];
+  char server_path[FN_REFLEN];
+  char operation[16];
+
+  MY_INIT(argv[0]);
+  plugin_data.name= 0; // initialize name
+  
+  /*
+    The following operations comprise the method for enabling or disabling
+    a plugin. We begin by processing the command options then check the
+    directories specified for --datadir, --basedir, --plugin-dir, and
+    --plugin-ini (if specified). If the directories are Ok, we then look
+    for the mysqld executable and the plugin soname. Finally, we build a
+    bootstrap command file for use in bootstraping the server.
+    
+    If any step fails, the method issues an error message and the tool exits.
+    
+      1) Parse, execute, and verify command options.
+      2) Check access to directories.
+      3) Look for mysqld executable.
+      4) Look for the plugin.
+      5) Build a bootstrap file with commands to enable or disable plugin.
+      
+  */
+  if ((error= process_options(argc, argv, operation)) ||
+      (error= check_access()) ||
+      (error= find_tool("mysqld" FN_EXEEXT, server_path)) ||
+      (error= find_plugin(tp_path)) ||
+      (error= build_bootstrap_file(operation, bootstrap)))
+    goto exit;
+  
+  /* Dump the bootstrap file if --verbose specified. */
+  if (opt_verbose && ((error= dump_bootstrap_file(bootstrap))))
+    goto exit;
+  
+  /* Start the server in bootstrap mode and execute bootstrap commands */
+  error= bootstrap_server(server_path, bootstrap);
+
+exit:
+  /* Remove file */
+  my_delete(bootstrap, MYF(0));
+  if (opt_verbose && error == 0)
+  {
+    printf("# Operation succeeded.\n");
+  }
+
+  my_end(my_end_arg);
+  exit(error ? 1 : 0);
+  return 0;        /* No compiler warnings */
+}
+
+
+/**
+  Get a temporary file name.
+
+  @param[out]  filename   The file name of the temporary file
+  @param[in]   ext        An extension for the file (optional)
+
+  @retval int error = 1, success = 0
+*/
+
+static int make_tempfile(char *filename, const char *ext)
+{
+  int fd= 0;
+
+  if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY,
+         MYF(MY_WME))) < 0)
+  {
+    fprintf(stderr, "ERROR: Cannot generate temporary file. Error code: %d.\n",
+            fd);
+    return 1;
+  }
+  my_close(fd, MYF(0));
+  return 0;
+}
+
+
+/**
+  Get the value of an option from a string read from my_print_defaults output.
+
+  @param[in]  line   The line (string) read from the file
+  @param[in]  item   The option to search for (e.g. --datadir)
+
+  @returns NULL if not found, string containing value if found
+*/
+
+static char *get_value(char *line, const char *item)
+{
+  char *destination= 0;
+  int item_len= (int)strlen(item);
+  int line_len = (int)strlen(line);
+
+  if ((strncasecmp(line, item, item_len) == 0))
+  {
+    int start= 0;
+    char *s= 0;
+
+    s = line + item_len + 1;
+    destination= my_strndup(s, line_len - start, MYF(MY_FAE));
+    destination[line_len - item_len - 2]= 0;
+  }
+  return destination;
+}
+
+
+/**
+  Run a command in a shell.
+
+  This function will attempt to execute the command specified by using the
+  popen() method to open a shell and execute the command passed and store the
+  output in a result file. If the --verbose option was specified, it will open
+  the result file and print the contents to stdout.
+
+  @param[in]  cmd   The command to execute.
+  @param[in]  mode  The mode for popen() (e.g. "r", "w", "rw")
+
+  @return int error code or 0 for success.
+*/
+
+static int run_command(char* cmd, const char *mode)
+{
+  char buf[512]= {0};
+  FILE *res_file;
+  int error;
+
+  if (!(res_file= popen(cmd, mode)))
+    return -1;
+
+  if (opt_verbose)
+  {
+    while (fgets(buf, sizeof(buf), res_file))
+    {
+      fprintf(stdout, "%s", buf);
+    }
+  }
+  error= pclose(res_file);
+  return error;
+}
+
+
+#ifdef __WIN__
+/**
+  Check to see if there are spaces in a path.
+  
+  @param[in]  path  The Windows path to examine.
+
+  @retval int spaces found = 1, no spaces = 0
+*/
+static int has_spaces(const char *path)
+{
+  if (strchr(path, ' ') != NULL)
+    return 1;
+  return 0;
+}
+
+
+/**
+  Convert a Unix path to a Windows path.
+ 
+  @param[in]  path  The Windows path to examine.
+
+  @returns string containing path with / changed to \\
+*/
+static char *convert_path(const char *argument)
+{
+  /* Convert / to \\ to make Windows paths */
+  char *winfilename= my_strdup(argument, MYF(MY_FAE));
+  char *pos, *end;
+  int length= strlen(argument);
+
+  for (pos= winfilename, end= pos+length ; pos < end ; pos++)
+  {
+    if (*pos == '/')
+    {
+      *pos= '\\';
+    }
+  }
+  return winfilename;
+}
+
+
+/**
+  Add quotes if the path has spaces in it.
+
+  @param[in]  path  The Windows path to examine.
+
+  @returns string containing excaped quotes if spaces found in path
+*/
+static char *add_quotes(const char *path)
+{
+  char windows_cmd_friendly[FN_REFLEN];
+
+  if (has_spaces(path))
+    snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly),
+             "\"%s\"", path);
+  else
+    snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly),
+             "%s", path);
+  return my_strdup(windows_cmd_friendly, MYF(MY_FAE));
+}
+#endif
+
+
+/**
+  Get the default values from the my.cnf file.
+
+  This method gets the default values for the following parameters:
+
+  --datadir
+  --basedir
+  --plugin-dir
+  --plugin-ini
+
+  These values are used if the user has not specified a value.
+
+  @retval int error = 1, success = 0
+*/
+
+static int get_default_values()
+{
+  char tool_path[FN_REFLEN];
+  char defaults_cmd[FN_REFLEN];
+  char defaults_file[FN_REFLEN];
+  char line[FN_REFLEN];
+  int error= 0;
+  int ret= 0;
+  FILE *file= 0;
+
+  bzero(tool_path, FN_REFLEN);
+  if ((error= find_tool("my_print_defaults" FN_EXEEXT, tool_path)))
+    goto exit;
+  else
+  {
+    if ((error= make_tempfile(defaults_file, "txt")))
+      goto exit;
+
+#ifdef __WIN__
+    {
+      char *format_str= 0;
+  
+      if (has_spaces(tool_path) || has_spaces(defaults_file))
+        format_str = "\"%s mysqld > %s\"";
+      else
+        format_str = "%s mysqld > %s";
+  
+      snprintf(defaults_cmd, sizeof(defaults_cmd), format_str,
+               add_quotes(tool_path), add_quotes(defaults_file));
+      if (opt_verbose)
+      {
+        printf("# my_print_defaults found: %s\n", tool_path);
+      }
+    }
+#else
+    snprintf(defaults_cmd, sizeof(defaults_cmd),
+             "%s mysqld > %s", tool_path, defaults_file);
+#endif
+
+    /* Execute the command */
+    if (opt_verbose)
+    {
+      printf("# Command: %s\n", defaults_cmd);
+    }
+    error= run_command(defaults_cmd, "r");
+    if (error)
+    {
+      fprintf(stderr, "ERROR: my_print_defaults failed. Error code: %d.\n",
+              ret);
+      goto exit;
+    }
+    /* Now open the file and read the defaults we want. */
+    file= fopen(defaults_file, "r");
+    while (fgets(line, FN_REFLEN, file) != NULL)
+    {
+      char *value= 0;
+
+      if ((opt_datadir == 0) && ((value= get_value(line, "--datadir"))))
+      {
+        opt_datadir= my_strdup(value, MYF(MY_FAE));
+      }
+      if ((opt_basedir == 0) && ((value= get_value(line, "--basedir"))))
+      {
+        opt_basedir= my_strdup(value, MYF(MY_FAE));
+      }
+      if ((opt_plugin_dir == 0) && ((value= get_value(line, "--plugin_dir"))))
+      {
+        opt_plugin_dir= my_strdup(value, MYF(MY_FAE));
+      }
+      if ((opt_plugin_ini == 0) && ((value= get_value(line, "--plugin_ini"))))
+      {
+        opt_plugin_ini= my_strdup(value, MYF(MY_FAE));
+      }
+    }
+  }
+exit:
+  if (file)
+  {
+    fclose(file);
+    /* Remove file */
+    my_delete(defaults_file, MYF(0));
+  }
+  return error;
+}
+
+
+/**
+  Print usage.
+*/
+
+static void usage(void)
+{
+  PRINT_VERSION;
+  puts("Copyright (c) 2011, Oracle and/or its affiliates. "
+       "All rights reserved.\n");
+  puts("Enable or disable plugins.");
+  printf("\nUsage: %s [options] <plugin> ENABLE|DISABLE\n\nOptions:\n",
+     my_progname);
+  my_print_help(my_long_options);
+  puts("\n");
+}
+
+
+/**
+  Print the default values as read from the my.cnf file.
+
+  This method displays the default values for the following parameters:
+
+  --datadir
+  --basedir
+  --plugin-dir
+  --plugin-ini
+
+*/
+
+static void print_default_values(void)
+{
+  printf("%s would have been started with the following arguments:\n",
+         my_progname);
+  get_default_values();
+  if (opt_datadir)
+  {
+    printf("--datadir=%s ", opt_datadir);
+  }
+  if (opt_basedir)
+  {
+    printf("--basedir=%s ", opt_basedir);
+  }
+  if (opt_plugin_dir)
+  {
+    printf("--plugin_dir=%s ", opt_plugin_dir);
+  }
+  if (opt_plugin_ini)
+  {
+    printf("--plugin_ini=%s ", opt_plugin_ini);
+  }
+  if (opt_mysqld)
+  {
+    printf("--mysqld=%s ", opt_mysqld);
+  }
+  if (opt_my_print_defaults)
+  {
+    printf("--my_print_defaults=%s ", opt_my_print_defaults);
+  }
+  printf("\n");
+}
+
+
+/**
+  Process the arguments and identify an option and store its value.
+
+  @param[in]  optid      The single character shortcut for the argument.
+  @param[in]  my_option  Structure of legal options.
+  @param[in]  argument   The argument value to process.
+*/
+
+static my_bool
+get_one_option(int optid,
+               const struct my_option *opt __attribute__((unused)),
+               char *argument)
+{
+  switch(optid) {
+  case 'n':
+    opt_no_defaults++;
+    break;
+  case 'P':
+    opt_print_defaults++;
+    print_default_values();
+    break;
+  case 'v':
+    opt_verbose++;
+    break;
+  case 'V':
+    PRINT_VERSION;
+    exit(0);
+    break;
+  case '?':
+  case 'I':          /* Info */
+    usage();
+    exit(0);
+  case 'd':
+    opt_datadir= my_strdup(argument, MYF(MY_FAE));
+    break;
+  case 'b':
+    opt_basedir= my_strdup(argument, MYF(MY_FAE));
+    break;
+  case 'p':
+    opt_plugin_dir= my_strdup(argument, MYF(MY_FAE));
+    break;
+  case 'i':
+    opt_plugin_ini= my_strdup(argument, MYF(MY_FAE));
+    break;
+  case 'm':
+    opt_mysqld= my_strdup(argument, MYF(MY_FAE));
+    break;
+  case 'f':
+    opt_my_print_defaults= my_strdup(argument, MYF(MY_FAE));
+    break;
+  }
+  return 0;
+}
+
+
+/**
+  Check to see if a file exists.
+
+  @param[in]  filename  File to locate.
+
+  @retval int file not found = 1, file found = 0
+*/
+
+static int file_exists(char * filename)
+{
+  MY_STAT stat_arg;
+
+  if (!my_stat(filename, &stat_arg, MYF(0)))
+  {
+    return 0;
+  }
+  return 1;
+}
+
+
+/**
+  Search a specific path and sub directory for a file name.
+
+  @param[in]  base_path  Original path to use.
+  @param[in]  tool_name  Name of the tool to locate.
+  @param[in]  subdir     The sub directory to search.
+  @param[out] tool_path  If tool found, return complete path.
+
+  @retval int error = 1, success = 0
+*/
+
+static int search_dir(const char * base_path, const char *tool_name,
+                      const char *subdir, char *tool_path)
+{
+  char new_path[FN_REFLEN];
+  char source_path[FN_REFLEN];
+
+  strcpy(source_path, base_path);
+  strcat(source_path, subdir);
+  fn_format(new_path, tool_name, source_path, "", MY_UNPACK_FILENAME);
+  if (file_exists(new_path))
+  {
+    strcpy(tool_path, new_path);
+    return 1;
+  }
+  return 0;
+}
+
+
+/**
+  Search known common paths and sub directories for a file name.
+
+  @param[in]  base_path  Original path to use.
+  @param[in]  tool_name  Name of the tool to locate.
+  @param[out] tool_path  If tool found, return complete path.
+
+  @retval int error = 1, success = 0
+*/
+
+static int search_paths(const char *base_path, const char *tool_name,
+                        char *tool_path)
+{
+  int i= 0;
+
+  static const char *paths[]= {
+    "", "/share/",  "/scripts/", "/bin/", "/sbin/", "/libexec/",
+    "/mysql/", "/sql/",
+  };
+  for (i = 0 ; i < (int)array_elements(paths); i++)
+  {
+    if (search_dir(base_path, tool_name, paths[i], tool_path))
+    {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+/**
+  Read the plugin ini file.
+
+  This function attempts to read the plugin config file from the plugin_dir
+  path saving the data in the the st_plugin structure. If the file is not
+  found or the file cannot be read, an error is generated.
+
+  @retval int error = 1, success = 0
+*/
+
+static int load_plugin_data(char *plugin_name, char *config_file)
+{
+  FILE *file_ptr;
+  char path[FN_REFLEN];
+  char line[1024];
+  char *reason= 0;
+  char *res;
+  int i= -1;
+
+  if (opt_plugin_ini == 0)
+  {
+    fn_format(path, config_file, opt_plugin_dir, "", MYF(0));
+    opt_plugin_ini= my_strdup(path, MYF(MY_FAE));
+  }
+  if (!file_exists(opt_plugin_ini))
+  {
+    reason= (char *)"File does not exist.";
+    goto error;
+  }
+
+  file_ptr= fopen(opt_plugin_ini, "r");
+  if (file_ptr == NULL)
+  {
+    reason= (char *)"Cannot open file.";
+    goto error;
+  }
+
+  /* save name */
+  plugin_data.name= my_strdup(plugin_name, MYF(MY_WME));
+
+  /* Read plugin components */
+  while (i < 16)
+  {
+    res= fgets(line, sizeof(line), file_ptr);
+    /* strip /n */
+    if (line[strlen(line)-1] == '\n')
+    {
+      line[strlen(line)-1]= '\0';
+    }
+    if (res == NULL)
+    {
+      if (i < 1)
+      {
+        reason= (char *)"Bad format in plugin configuration file.";
+        fclose(file_ptr);
+        goto error;        
+      }
+      break;
+    }
+    if ((line[0] == '#') || (line[0] == '\n')) // skip comment and blank lines
+    {
+      continue;
+    }
+    if (i == -1) // if first pass, read this line as so_name
+    {
+      /* Add proper file extension for soname */
+      strcat(line, FN_SOEXT);
+      /* save so_name */
+      plugin_data.so_name= my_strdup(line, MYF(MY_WME|MY_ZEROFILL));
+      i++;
+    }
+    else
+    {
+      if (strlen(line) > 0)
+      {
+        plugin_data.components[i]= my_strdup(line, MYF(MY_WME));
+        i++;
+      }
+      else
+      {
+        plugin_data.components[i]= NULL;
+      }
+    }
+  }
+  
+  fclose(file_ptr);
+  return 0;
+
+error:
+  fprintf(stderr, "ERROR: Cannot read plugin config file %s. %s\n",
+          plugin_name, reason);
+  return 1;
+}
+
+
+/**
+  Check the options for validity.
+
+  This function checks the arguments for validity issuing the appropriate
+  error message if arguments are missing or invalid. On success, @operation
+  is set to either "ENABLE" or "DISABLE".
+
+  @param[in]  argc       The number of arguments.
+  @param[in]  argv       The arguments.
+  @param[out] operation  The operation chosen (enable|disable)
+
+  @retval int error = 1, success = 0
+*/
+
+static int check_options(int argc, char **argv, char *operation)
+{
+  int i= 0;                    // loop counter
+  int num_found= 0;            // number of options found (shortcut loop)
+  char config_file[FN_REFLEN]; // configuration file name
+  char plugin_name[FN_REFLEN]; // plugin name
+  
+  /* Form prefix strings for the options. */
+  const char *basedir_prefix = "--basedir=";
+  int basedir_len= strlen(basedir_prefix);
+  const char *datadir_prefix = "--datadir=";
+  int datadir_len= strlen(datadir_prefix);
+  const char *plugin_dir_prefix = "--plugin_dir=";
+  int plugin_dir_len= strlen(plugin_dir_prefix);
+
+  strcpy(plugin_name, "");
+  for (i = 0; i < argc && num_found < 5; i++)
+  {
+
+    if (!argv[i])
+    {
+      continue;
+    }
+    if ((strcasecmp(argv[i], "ENABLE") == 0) ||
+        (strcasecmp(argv[i], "DISABLE") == 0))
+    {
+      strcpy(operation, argv[i]);
+      num_found++;
+    }
+    else if ((strncasecmp(argv[i], basedir_prefix, basedir_len) == 0) &&
+             !opt_basedir)
+    {
+      opt_basedir= my_strndup(argv[i]+basedir_len,
+                              strlen(argv[i])-basedir_len, MYF(MY_FAE));
+      num_found++;
+    }
+    else if ((strncasecmp(argv[i], datadir_prefix, datadir_len) == 0) &&
+             !opt_datadir)
+    {
+      opt_datadir= my_strndup(argv[i]+datadir_len,
+                              strlen(argv[i])-datadir_len, MYF(MY_FAE));
+      num_found++;
+    }
+    else if ((strncasecmp(argv[i], plugin_dir_prefix, plugin_dir_len) == 0) &&
+             !opt_plugin_dir)
+    {
+      opt_plugin_dir= my_strndup(argv[i]+plugin_dir_len,
+                                 strlen(argv[i])-plugin_dir_len, MYF(MY_FAE));
+      num_found++;
+    }
+    /* read the plugin config file and check for match against argument */
+    else
+    {
+      strcpy(plugin_name, argv[i]);
+      strcpy(config_file, argv[i]);
+      strcat(config_file, ".ini");
+    }
+  }
+
+  if (!opt_basedir)
+  {
+    fprintf(stderr, "ERROR: Missing --basedir option.\n");
+    return 1;
+  }
+
+  if (!opt_datadir)
+  {
+    fprintf(stderr, "ERROR: Missing --datadir option.\n");
+    return 1;
+  }
+
+  if (!opt_plugin_dir)
+  {
+    fprintf(stderr, "ERROR: Missing --plugin_dir option.\n");
+    return 1;
+  }
+  /* If a plugin was specified, read the config file. */
+  else if (strlen(plugin_name) > 0) 
+  {
+    if (load_plugin_data(plugin_name, config_file))
+    {
+      return 1;
+    }
+    if (strcasecmp(plugin_data.name, plugin_name) != 0)
+    {
+      fprintf(stderr, "ERROR: plugin name requested does not match config "
+              "file data.\n");
+      return 1;
+    }
+  }
+  else
+  {
+    fprintf(stderr, "ERROR: No plugin specified.\n");
+    return 1;
+  }
+
+  if ((strlen(operation) == 0))
+  {
+    fprintf(stderr, "ERROR: missing operation. Please specify either "
+            "'<plugin> ENABLE' or '<plugin> DISABLE'.\n");
+    return 1;
+  }
+
+  return 0;
+}
+
+
+/**
+  Parse, execute, and verify command options.
+  
+  This method handles all of the option processing including the optional
+  features for displaying data (--print-defaults, --help ,etc.) that do not
+  result in an attempt to ENABLE or DISABLE of a plugin.
+  
+  @param[in]   arc        Count of arguments
+  @param[in]   argv       Array of arguments
+  @param[out]  operation  Operation (ENABLE or DISABLE)
+  
+  @retval int error = 1, success = 0, exit program = -1
+*/
+
+static int process_options(int argc, char *argv[], char *operation)
+{
+  int error= 0;
+  int i= 0;
+  
+  /* Parse and execute command-line options */
+  if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
+    goto exit;
+
+  /* If the print defaults option used, exit. */
+  if (opt_print_defaults)
+  {
+    error= -1;
+    goto exit;
+  }
+
+  /* Add a trailing directory separator if not present */
+  if (opt_basedir)
+  {
+    i= (int)strlength(opt_basedir);
+    if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2)
+#ifdef __WIN__
+      if (opt_basedir[i-1] != '/')
+        strcat(opt_basedir, "//");
+#else
+      strcat(opt_basedir, FN_DIRSEP);
+#endif
+  }
+  
+  /*
+    If the user did not specify the option to skip loading defaults from a
+    config file and the required options are not present or there was an error
+    generated when the defaults were read from the file, exit.
+  */
+  if (!opt_no_defaults && ((error= get_default_values())))
+  {
+    error= -1;
+    goto exit;
+  }
+
+  /*
+   Check to ensure required options are present and validate the operation.
+   Note: this method also validates the plugin specified by attempting to
+   read a configuration file named <plugin_name>.ini from the --plugin-dir
+   or --plugin-ini location if the --plugin-ini option presented.
+  */
+  strcpy(operation, "");
+  if ((error = check_options(argc, argv, operation)))
+  {
+    goto exit;
+  }
+
+  if (opt_verbose)
+  {
+    printf("#    basedir = %s\n", opt_basedir);
+    printf("# plugin_dir = %s\n", opt_plugin_dir);
+    printf("#    datadir = %s\n", opt_datadir);
+    printf("# plugin_ini = %s\n", opt_plugin_ini);
+  }
+
+exit:
+  return error;
+}
+
+
+/**
+  Check access
+  
+  This method checks to ensure all of the directories (opt_basedir,
+  opt_plugin_dir, opt_datadir, and opt_plugin_ini) are accessible by
+  the user.
+  
+  @retval int error = 1, success = 0
+*/
+
+static int check_access()
+{
+  int error= 0;
+  
+  if ((error= my_access(opt_basedir, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access basedir at '%s'.\n",
+            opt_basedir);
+    goto exit;
+  }
+  if ((error= my_access(opt_plugin_dir, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access plugin_dir at '%s'.\n",
+            opt_plugin_dir);
+    goto exit;
+  }
+  if ((error= my_access(opt_datadir, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access datadir at '%s'.\n",
+            opt_datadir);
+    goto exit;
+  }
+  if ((error= my_access(opt_plugin_ini, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access plugin config file at '%s'.\n",
+            opt_plugin_ini);
+    goto exit;
+  }
+  if ((error= my_access(opt_mysqld, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access mysqld path '%s'.\n",
+            opt_mysqld);
+    goto exit;
+  }
+  if ((error= my_access(opt_my_print_defaults, F_OK)))
+  {
+    fprintf(stderr, "ERROR: Cannot access my-print-defaults path '%s'.\n",
+            opt_my_print_defaults);
+    goto exit;
+  }
+
+exit:
+  return error;
+}
+
+
+/**
+  Locate the tool and form tool path.
+
+  @param[in]  tool_name  Name of the tool to locate.
+  @param[out] tool_path  If tool found, return complete path.
+
+  @retval int error = 1, success = 0
+*/
+
+static int find_tool(const char *tool_name, char *tool_path)
+{
+  int i= 0;
+
+  const char *paths[]= {
+    opt_basedir, opt_mysqld, opt_my_print_defaults, "/usr",
+    "/usr/local/mysql", "/usr/sbin", "/usr/share", "/extra", "/extra/debug",
+    "/extra/release", "/bin", "/usr/bin", "/mysql/bin"
+  };
+  for (i= 0; i < (int)array_elements(paths); i++)
+  {
+    if (paths[i] && (search_paths(paths[i], tool_name, tool_path)))
+      goto found;
+  }
+  fprintf(stderr, "WARNING: Cannot find %s.\n", tool_name);
+  return 1;
+found:
+  if (opt_verbose)
+    printf("# Found tool '%s' as '%s'.\n", tool_name, tool_path);
+  return 0;
+}
+
+
+/**
+  Find the plugin library.
+
+  This function attempts to use the @c plugin_dir option passed on the
+  command line to locate the plugin.
+
+  @param[out] tp_path   The actual path to plugin with FN_SOEXT applied.
+
+  @retval int error = 1, success = 0
+*/
+
+static int find_plugin(char *tp_path)
+{
+  /* Check for existance of plugin */
+  fn_format(tp_path, plugin_data.so_name, opt_plugin_dir, "", MYF(0));
+  if (!file_exists(tp_path))
+  {
+    fprintf(stderr, "ERROR: The plugin library is missing or in a different"
+            " location.\n");
+    return 1;
+  }
+  else if (opt_verbose)
+  {
+    printf("# Found plugin '%s' as '%s'\n", plugin_data.name, tp_path);
+  }
+  return 0;
+}
+
+
+/**
+  Build the boostrap file.
+  
+  Create a new file and populate it with SQL commands to ENABLE or DISABLE
+  the plugin via INSERT and DELETE operations on the mysql.plugin table.
+
+  param[in]  operation  The type of operation (ENABLE or DISABLE)
+  param[out] bootstrap  A FILE* pointer
+  
+  @retval int error = 1, success = 0
+*/
+
+static int build_bootstrap_file(char *operation, char *bootstrap)
+{
+  int error= 0;
+  FILE *file= 0;
+  
+  /*
+    Perform plugin operation : ENABLE or DISABLE
+
+    The following creates a temporary bootstrap file and populates it with
+    the appropriate SQL commands for the operation. For ENABLE, INSERT
+    statements are created. For DISABLE, DELETE statements are created. The
+    values for these statements are derived from the plugin_data read from the
+    <plugin_name>.ini configuration file. Once the file is built, a call to
+    mysqld is made in read only, bootstrap modes to read the SQL statements
+    and execute them.
+  */
+  if ((error= make_tempfile(bootstrap, "sql")))
+  {
+    /* Fail if we cannot create a temporary file for the bootstrap commands. */
+    fprintf(stderr, "ERROR: Cannot create bootstrap file.\n");
+    goto exit;
+  }
+  if ((file= fopen(bootstrap, "w+")) == NULL)
+  {
+    fprintf(stderr, "ERROR: Cannot open bootstrap file for writing.\n");
+    error= 1;
+    goto exit;
+  }
+  if (strcasecmp(operation, "enable") == 0)
+  {
+    int i= 0;
+    fprintf(file, "INSERT IGNORE INTO mysql.plugin VALUES ");
+    for (i= 0; i < (int)array_elements(plugin_data.components); i++)
+    {
+      /* stop when we read the end of the symbol list - marked with NULL */
+      if (plugin_data.components[i] == NULL)
+      {
+        break;
+      }
+      if (i > 0)
+      {
+        fprintf(file, ", ");
+      }
+      fprintf(file, "('%s','%s')",
+              plugin_data.components[i], plugin_data.so_name);
+    }
+    fprintf(file, ";\n");
+    if (opt_verbose)
+    {
+      printf("# Enabling %s...\n", plugin_data.name);
+    }
+  }
+  else
+  {
+    fprintf(file,
+            "DELETE FROM mysql.plugin WHERE name = '%s';", plugin_data.name);
+    if (opt_verbose)
+    {
+      printf("# Disabling %s...\n", plugin_data.name);
+    }
+  }
+  
+exit:
+  fclose(file);
+  return error;
+}
+
+
+/**
+  Dump bootstrap file.
+  
+  Read the contents of the bootstrap file and print it out.
+  
+  @param[in]  bootstrap_file  Name of bootstrap file to read
+  
+  @retval int error = 1, success = 0
+*/
+
+static int dump_bootstrap_file(char *bootstrap_file)
+{
+  char *ret= 0;
+  int error= 0;
+  char query_str[512];
+  FILE *file= 0;
+
+  if ((file= fopen(bootstrap_file, "r")) == NULL)
+  {
+    fprintf(stderr, "ERROR: Cannot open bootstrap file for reading.\n");
+    error= 1;
+    goto exit;
+  }
+  ret= fgets(query_str, 512, file);
+  if (ret == 0)
+  {
+    fprintf(stderr, "ERROR: Cannot read bootstrap file.\n");
+    error= 1;
+    goto exit;
+  }
+  printf("# Query: %s", query_str);
+
+exit:
+  if (file)
+  {
+    fclose(file);
+  }
+  return error;
+}
+
+
+/**
+  Bootstrap the server
+  
+  Create a command line sequence to launch mysqld in bootstrap mode. This
+  will allow mysqld to launch a minimal server instance to read and
+  execute SQL commands from a file piped in (the boostrap file). We use
+  the --no-defaults option to skip reading values from the config file.
+
+  The bootstrap mode skips loading of plugins and many other subsystems.
+  This allows the mysql_plugin tool to insert the correct rows into the
+  mysql.plugin table (for ENABLE) or delete the rows (for DISABLE). Once
+  the server is launched in normal mode, the plugin will be loaded
+  (for ENABLE) or not loaded (for DISABLE). In this way, we avoid the
+  (sometimes) complicated LOAD PLUGIN commands.
+
+  @param[in]  server_path     Path to server executable
+  @param[in]  bootstrap_file  Name of bootstrap file to read
+
+  @retval int error = 1, success = 0
+*/
+
+static int bootstrap_server(char *server_path, char *bootstrap_file)
+{
+  char bootstrap_cmd[FN_REFLEN];
+  int error= 0;
+  int ret= 0;
+
+#ifdef __WIN__
+  char *format_str= 0;
+  char *verbose_str= "";
+  
+  if (opt_verbose)
+    strcat(verbose_str, "--console");
+  if (has_spaces(opt_datadir) || has_spaces(opt_basedir) ||
+      has_spaces(bootstrap_file))
+    format_str= "\"%s %s --bootstrap --datadir=%s --basedir=%s < %s\"";
+  else 
+    format_str= "%s %s --bootstrap --datadir=%s --basedir=%s < %s";
+
+  snprintf(bootstrap_cmd, sizeof(bootstrap_cmd), format_str,
+           add_quotes(convert_path(server_path)), verbose_str,
+           add_quotes(opt_datadir), add_quotes(opt_basedir),
+           add_quotes(bootstrap_file));
+#else
+  snprintf(bootstrap_cmd, sizeof(bootstrap_cmd),
+           "%s --no-defaults --bootstrap --datadir=%s --basedir=%s"
+           " < %s", server_path, opt_datadir, opt_basedir, bootstrap_file);
+#endif
+
+  /* Execute the command */
+  if (opt_verbose)
+  {
+    printf("# Command: %s\n", bootstrap_cmd);
+  }
+  error= run_command(bootstrap_cmd, "r");
+  if (error)
+    fprintf(stderr,
+            "ERROR: Unexpected result from bootstrap. Error code: %d.\n",
+            ret);
+  
+  return error;
+}

=== modified file 'include/my_base.h'
--- a/include/my_base.h	2011-06-30 15:46:53 +0000
+++ b/include/my_base.h	2011-08-17 01:07:59 +0000
@@ -446,8 +446,9 @@ enum ha_base_keytype {
 #define HA_ERR_FILE_TOO_SHORT	  175	 /* File too short */
 #define HA_ERR_WRONG_CRC	  176	 /* Wrong CRC on page */
 #define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */
-#define HA_ERR_INDEX_COL_TOO_LONG 178	/* Index column length exceeds limit */
-#define HA_ERR_LAST               178    /* Copy of last error nr */
+#define HA_ERR_INDEX_COL_TOO_LONG 178	 /* Index column length exceeds limit */
+#define HA_ERR_INDEX_CORRUPT      179	 /* Index corrupted */
+#define HA_ERR_LAST               179    /* Copy of last error nr */
 
 /* Number of different errors */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)

=== modified file 'include/my_global.h'
--- a/include/my_global.h	2011-07-03 23:48:19 +0000
+++ b/include/my_global.h	2011-07-19 14:17:58 +0000
@@ -603,6 +603,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
 #define FN_LIBCHAR	'\\'
 #define FN_LIBCHAR2	'/'
 #define FN_DIRSEP       "/\\"               /* Valid directory separators */
+#define FN_EXEEXT   ".exe"
+#define FN_SOEXT    ".dll"
 #define FN_ROOTDIR	"\\"
 #define FN_DEVCHAR	':'
 #define FN_NETWORK_DRIVES	/* Uses \\ to indicate network drives */
@@ -611,6 +613,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
 #define FN_LIBCHAR	'/'
 #define FN_LIBCHAR2	'/'
 #define FN_DIRSEP       "/"     /* Valid directory separators */
+#define FN_EXEEXT   ""
+#define FN_SOEXT    ".so"
 #define FN_ROOTDIR	"/"
 #endif
 

=== added file 'mysql-test/include/daemon_example_bad_format.ini'
--- a/mysql-test/include/daemon_example_bad_format.ini	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/daemon_example_bad_format.ini	2011-07-19 14:27:15 +0000
@@ -0,0 +1,8 @@
+#
+# Plugin configuration file. Place the following on a separate line:
+#
+# library binary file name (without .so or .dll)
+# component_name
+# [component_name] - additional components in plugin
+#
+libdaemon_example   

=== added file 'mysql-test/include/daemon_example_bad_soname.ini'
--- a/mysql-test/include/daemon_example_bad_soname.ini	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/daemon_example_bad_soname.ini	2011-07-19 14:27:15 +0000
@@ -0,0 +1,9 @@
+#
+# Plugin configuration file. Place the following on a separate line:
+#
+# library binary file name (without .so or .dll)
+# component_name
+# [component_name] - additional components in plugin
+#
+libdaemon_BADNAME
+daemon_BADNAME

=== modified file 'mysql-test/include/plugin.defs'
--- a/mysql-test/include/plugin.defs	2011-05-30 13:55:44 +0000
+++ b/mysql-test/include/plugin.defs	2011-07-19 14:17:58 +0000
@@ -39,3 +39,4 @@ ha_archive         storage/archive    AR
 ha_blackhole       storage/blackhole  BLACKHOLE_PLUGIN
 ha_federated       storage/federated  FEDERATED_PLUGIN
 mypluglib          plugin/fulltext    SIMPLE_PARSER
+libdaemon_example  plugin/daemon_example DAEMONEXAMPLE

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-07-15 15:12:23 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-07-19 14:17:58 +0000
@@ -168,6 +168,7 @@ my $opt_suites;
 
 our $opt_verbose= 0;  # Verbose output, enable with --verbose
 our $exe_mysql;
+our $exe_mysql_plugin;
 our $exe_mysqladmin;
 our $exe_mysqltest;
 our $exe_libtool;
@@ -1950,6 +1951,7 @@ sub executable_setup () {
   # Look for the client binaries
   $exe_mysqladmin=     mtr_exe_exists("$path_client_bindir/mysqladmin");
   $exe_mysql=          mtr_exe_exists("$path_client_bindir/mysql");
+  $exe_mysql_plugin=   mtr_exe_exists("$path_client_bindir/mysql_plugin");
 
   $exe_mysql_embedded= mtr_exe_maybe_exists("$basedir/libmysqld/examples/mysql_embedded");
 
@@ -2357,6 +2359,7 @@ sub environment_setup {
   $ENV{'MYSQLADMIN'}=               native_path($exe_mysqladmin);
   $ENV{'MYSQL_CLIENT_TEST'}=        mysql_client_test_arguments();
   $ENV{'EXE_MYSQL'}=                $exe_mysql;
+  $ENV{'MYSQL_PLUGIN'}=             $exe_mysql_plugin;
   $ENV{'MYSQL_EMBEDDED'}=           $exe_mysql_embedded;
 
   # ----------------------------------------------------

=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result	2010-12-17 11:11:34 +0000
+++ b/mysql-test/r/information_schema.result	2011-08-11 15:58:49 +0000
@@ -1849,5 +1849,119 @@ unlock tables;
 drop table t1;
 drop view v1;
 #
+# Test for bug #12828477 - "MDL SUBSYSTEM CREATES BIG OVERHEAD FOR
+#                           CERTAIN QUERIES TO INFORMATION_SCHEMA".
+#
+# Check that metadata locks which are acquired during the process
+# of opening tables/.FRMs/.TRG files while filling I_S table are
+# not kept to the end of statement. Keeping the locks has caused
+# performance problems in cases when big number of tables (.FRMs
+# or .TRG files) were scanned as cost of new lock acquisition has
+# increased linearly.
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+create table t0 (i int);
+create table t1 (j int);
+create table t2 (k int);
+#
+# Test that we don't keep locks in case when we to fill
+# I_S table we perform full-blown table open.
+#
+# Acquire lock on 't2' so upcoming RENAME is
+# blocked.
+lock tables t2 read;
+#
+# Switching to connection 'con12828477_1'. 
+#
+# The below RENAME should wait on 't2' while
+# keeping X lock on 't1'.
+rename table t1 to t3, t2 to t1, t3 to t2;
+#
+# Switching to connection 'con12828477_2'. 
+#
+# Wait while the above RENAME is blocked.
+# Issue query to I_S which will open 't0' and get
+# blocked on 't1' because of RENAME.
+select table_name, auto_increment from information_schema.tables where table_schema='mysqltest';
+#
+# Switching to connection 'con12828477_3'. 
+#
+# Wait while the above SELECT is blocked.
+#
+# Check that it holds no lock on 't0' so it can be renamed.
+rename table t0 to t4;
+#
+# Switching to connection 'default'.
+#
+#
+# Unblock the first RENAME.
+unlock tables;
+#
+# Switching to connection 'con12828477_1'. 
+#
+# Reap the first RENAME
+#
+# Switching to connection 'con12828477_2'. 
+#
+# Reap SELECT to I_S.
+table_name	auto_increment
+t0	NULL
+t1	NULL
+t2	NULL
+#
+# Switching to connection 'default'.
+#
+#
+# Now test that we don't keep locks in case when we to fill
+# I_S table we read .FRM or .TRG file only (this was the case
+# for which problem existed).
+#
+rename table t4 to t0;
+# Acquire lock on 't2' so upcoming RENAME is
+# blocked.
+lock tables t2 read;
+#
+# Switching to connection 'con12828477_1'. 
+#
+# The below RENAME should wait on 't2' while
+# keeping X lock on 't1'.
+rename table t1 to t3, t2 to t1, t3 to t2;
+#
+# Switching to connection 'con12828477_2'. 
+#
+# Wait while the above RENAME is blocked.
+# Issue query to I_S which will open 't0' and get
+# blocked on 't1' because of RENAME.
+select event_object_table, trigger_name from information_schema.triggers where event_object_schema='mysqltest';
+#
+# Switching to connection 'con12828477_3'. 
+#
+# Wait while the above SELECT is blocked.
+#
+# Check that it holds no lock on 't0' so it can be renamed.
+rename table t0 to t4;
+#
+# Switching to connection 'default'.
+#
+#
+# Unblock the first RENAME.
+unlock tables;
+#
+# Switching to connection 'con12828477_1'. 
+#
+# Reap the first RENAME
+#
+# Switching to connection 'con12828477_2'. 
+#
+# Reap SELECT to I_S.
+event_object_table	trigger_name
+#
+# Switching to connection 'default'.
+#
+#
+# Clean-up.
+drop database mysqltest;
+#
 # End of 5.5 tests
 #

=== added file 'mysql-test/r/mysql_plugin.result'
--- a/mysql-test/r/mysql_plugin.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/mysql_plugin.result	2011-08-09 12:58:18 +0000
@@ -0,0 +1,110 @@
+#
+# Ensure the plugin isn't loaded.
+#
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+name	dl
+#
+# Enable the plugin...
+#
+#
+# Ensure the plugin is now loaded.
+#
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+name	dl
+daemon_example	libdaemon_example.so
+#
+# Disable the plugin...
+#
+#
+# Ensure the plugin isn't loaded.
+#
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+name	dl
+#
+# Attempt to load non-existant plugin
+#
+ERROR: Cannot read plugin config file NOT_THERE_AT_ALL. File does not exist.
+#
+# Attempt to use non-existant plugin.ini file
+#
+ERROR: Cannot read plugin config file daemon_example. File does not exist.
+# 
+# Attempt to omit the plugin
+#
+ERROR: No plugin specified.
+# 
+# Attempt to omit DISABLE|ENABLE
+#
+ERROR: missing operation. Please specify either '<plugin> ENABLE' or '<plugin> DISABLE'.
+# 
+# Attempt to use bad paths - datadir
+#
+ERROR: Cannot access datadir at '/data_not_there/'.
+# 
+# Attempt to use bad paths - basedir
+#
+ERROR: Cannot access basedir at '/basedir_not_there/'.
+# 
+# Attempt to use bad paths - plugin_dir
+#
+ERROR: Cannot read plugin config file daemon_example. File does not exist.
+# 
+# Attempt to use bad paths - mysqld
+#
+ERROR: Cannot access mysqld path '/mysqld_not_there/'.
+# 
+# Attempt to use bad paths - my_print_defaults
+#
+ERROR: Cannot access my-print-defaults path '/my_print_defaults_not_there/'.
+# 
+# Missing library
+#
+ERROR: The plugin library is missing or in a different location.
+# 
+# Bad format for config file
+#
+ERROR: Cannot read plugin config file daemon_example. Bad format in plugin configuration file.
+# 
+# Missing base_dir option
+#
+ERROR: Missing --basedir option.
+# 
+# Missing data_dir option
+#
+ERROR: Missing --datadir option.
+# 
+# Missing plugin_dir option
+#
+ERROR: Missing --plugin_dir option.
+#
+# Show the help.
+#
+mysql_plugin  Ver V.V.VV Distrib XX.XX.XX
+Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+Enable or disable plugins.
+
+Usage: mysql_plugin [options] <plugin> ENABLE|DISABLE
+
+Options:
+  -?, --help          Display this help and exit.
+  -b, --basedir=name  The basedir for the server.
+  -d, --datadir=name  The datadir for the server.
+  -p, --plugin-dir=name 
+                      The plugin dir for the server.
+  -i, --plugin-ini=name 
+                      Read plugin information from configuration file specified
+                      instead of from <plugin-dir>/<plugin_name>.ini.
+  -n, --no-defaults   Do not read values from configuration file.
+  -P, --print-defaults 
+                      Show default values from configuration file.
+  -m, --mysqld=name   Path to mysqld executable. Example: /sbin/temp1/mysql/bin
+  -f, --my-print-defaults=name 
+                      Path to my_print_defaults executable. Example:
+                      /source/temp11/extra
+  -v, --verbose       More verbose output; you can use this multiple times to
+                      get even more verbose output.
+  -V, --version       Output version information and exit.
+
+
+mysql_plugin  Ver V.V.VV Distrib XX.XX.XX

=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result	2011-06-21 15:24:44 +0000
+++ b/mysql-test/r/sp.result	2011-08-02 07:54:35 +0000
@@ -7161,6 +7161,25 @@ init_connect
 SET @@GLOBAL.init_connect= @old_init_connect;
 DROP PROCEDURE p2;
 DROP PROCEDURE p5;
+#
+# Bug#11766594  59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C
+#
+CREATE TABLE t1 (a INT, b INT, KEY(b));
+CREATE TABLE t2 (c INT, d INT, KEY(c));
+INSERT INTO t1 VALUES (1,1),(1,1),(1,2);
+INSERT INTO t2 VALUES (1,1),(1,2);
+CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
+BEGIN
+DECLARE a int;
+-- SQL statement inside
+SELECT 1 INTO a;
+RETURN a;
+END $
+SELECT COUNT(DISTINCT d) FROM t1, t2  WHERE a = c AND b = f1();
+COUNT(DISTINCT d)
+2
+DROP FUNCTION f1;
+DROP TABLE t1, t2;
 # ------------------------------------------------------------------
 # -- End of 5.1 tests
 # ------------------------------------------------------------------

=== modified file 'mysql-test/r/sp_trans.result'
--- a/mysql-test/r/sp_trans.result	2010-10-06 14:34:28 +0000
+++ b/mysql-test/r/sp_trans.result	2011-08-08 16:45:43 +0000
@@ -558,6 +558,52 @@ f1	bug13575(f1)
 3	ccc
 drop function bug13575|
 drop table t3|
+SELECT @@GLOBAL.storage_engine INTO @old_engine|
+SET @@GLOBAL.storage_engine=InnoDB|
+SET @@SESSION.storage_engine=InnoDB|
+SHOW GLOBAL VARIABLES LIKE 'storage_engine'|
+Variable_name	Value
+storage_engine	InnoDB
+SHOW SESSION VARIABLES LIKE 'storage_engine'|
+Variable_name	Value
+storage_engine	InnoDB
+CREATE PROCEDURE bug11758414()
+BEGIN
+SET @@GLOBAL.storage_engine="MyISAM";
+SET @@SESSION.storage_engine="MyISAM"; 
+# show defaults at execution time / that setting them worked
+SHOW GLOBAL VARIABLES LIKE 'storage_engine';
+SHOW SESSION VARIABLES LIKE 'storage_engine';
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int) ENGINE=InnoDB;
+# show we're heeding the default (at run-time, not parse-time!)
+ SHOW CREATE TABLE t1;
+ # show that we didn't break explicit override with ENGINE=...
+SHOW CREATE TABLE t2;
+END;
+|
+CALL bug11758414|
+Variable_name	Value
+storage_engine	MyISAM
+Variable_name	Value
+storage_engine	MyISAM
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `id` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW GLOBAL VARIABLES LIKE 'storage_engine'|
+Variable_name	Value
+storage_engine	MyISAM
+SHOW SESSION VARIABLES LIKE 'storage_engine'|
+Variable_name	Value
+storage_engine	MyISAM
+DROP PROCEDURE bug11758414|
+DROP TABLE t1, t2|
+SET @@GLOBAL.storage_engine=@old_engine|
 #
 # End of 5.1 tests
 #

=== modified file 'mysql-test/suite/innodb/r/innodb-zip.result'
--- a/mysql-test/suite/innodb/r/innodb-zip.result	2010-11-02 23:19:29 +0000
+++ b/mysql-test/suite/innodb/r/innodb-zip.result	2011-08-08 09:16:15 +0000
@@ -63,42 +63,42 @@ row_format=compressed;
 create table t14(a int primary key) engine=innodb key_block_size=9;
 Warnings:
 Warning	1478	InnoDB: ignoring KEY_BLOCK_SIZE=9.
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t0	Compact
-test	t00	Compact
-test	t1	Compact
-test	t10	Dynamic
-test	t11	Compressed
-test	t12	Compressed
-test	t13	Compressed
-test	t14	Compact
-test	t2	Redundant
-test	t3	Compact
-test	t4	Compact
-test	t5	Redundant
-test	t6	Redundant
-test	t7	Redundant
-test	t8	Compact
-test	t9	Compact
+table_schema	table_name	row_format	data_length	index_length
+test	t0	Compact	16384	0
+test	t00	Compact	16384	0
+test	t1	Compact	16384	0
+test	t10	Dynamic	16384	0
+test	t11	Compressed	1024	0
+test	t12	Compressed	1024	0
+test	t13	Compressed	8192	0
+test	t14	Compact	16384	0
+test	t2	Redundant	16384	0
+test	t3	Compact	16384	0
+test	t4	Compact	16384	0
+test	t5	Redundant	16384	0
+test	t6	Redundant	16384	0
+test	t7	Redundant	16384	0
+test	t8	Compact	16384	0
+test	t9	Compact	16384	0
 drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14;
 alter table t1 key_block_size=0;
 alter table t1 row_format=dynamic;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Dynamic
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Dynamic	16384	0
 alter table t1 row_format=compact;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Compact
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Compact	16384	0
 alter table t1 row_format=redundant;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Redundant
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Redundant	16384	0
 drop table t1;
 create table t1(a int not null, b text, index(b(10))) engine=innodb
 key_block_size=1;
@@ -115,11 +115,11 @@ rollback;
 select a,left(b,40) from t1 natural join t2;
 a	left(b,40)
 1	1abcdefghijklmnopqrstuvwxyzAAAAAAAAAAAAA
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Compressed
-test	t2	Compact
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Compressed	2048	1024
+test	t2	Compact	16384	0
 drop table t1,t2;
 SET SESSION innodb_strict_mode = off;
 CREATE TABLE t1(
@@ -207,19 +207,19 @@ create table t8 (id int primary key) eng
 create table t9 (id int primary key) engine = innodb row_format = dynamic;
 create table t10(id int primary key) engine = innodb row_format = compact;
 create table t11(id int primary key) engine = innodb row_format = redundant;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Compact
-test	t10	Compact
-test	t11	Redundant
-test	t3	Compressed
-test	t4	Compressed
-test	t5	Compressed
-test	t6	Compressed
-test	t7	Compressed
-test	t8	Compressed
-test	t9	Dynamic
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Compact	16384	0
+test	t10	Compact	16384	0
+test	t11	Redundant	16384	0
+test	t3	Compressed	1024	0
+test	t4	Compressed	2048	0
+test	t5	Compressed	4096	0
+test	t6	Compressed	8192	0
+test	t7	Compressed	16384	0
+test	t8	Compressed	8192	0
+test	t9	Dynamic	16384	0
 drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11;
 create table t1 (id int primary key) engine = innodb
 key_block_size = 8 row_format = compressed;
@@ -246,11 +246,11 @@ Warning	1478	InnoDB: cannot specify ROW_
 Error	1005	Can't create table 'test.t4' (errno: 1478)
 create table t5 (id int primary key) engine = innodb
 key_block_size = 8 row_format = default;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t1	Compressed
-test	t5	Compressed
+table_schema	table_name	row_format	data_length	index_length
+test	t1	Compressed	8192	0
+test	t5	Compressed	8192	0
 drop table t1, t5;
 create table t1 (id int primary key) engine = innodb
 key_block_size = 9 row_format = redundant;
@@ -276,9 +276,9 @@ Level	Code	Message
 Warning	1478	InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
 Warning	1478	InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
 Error	1005	Can't create table 'test.t2' (errno: 1478)
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
+table_schema	table_name	row_format	data_length	index_length
 set global innodb_file_per_table = off;
 create table t1 (id int primary key) engine = innodb key_block_size = 1;
 ERROR HY000: Can't create table 'test.t1' (errno: 1478)
@@ -324,11 +324,11 @@ Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC 
 Error	1005	Can't create table 'test.t7' (errno: 1478)
 create table t8 (id int primary key) engine = innodb row_format = compact;
 create table t9 (id int primary key) engine = innodb row_format = redundant;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t8	Compact
-test	t9	Redundant
+table_schema	table_name	row_format	data_length	index_length
+test	t8	Compact	16384	0
+test	t9	Redundant	16384	0
 drop table t8, t9;
 set global innodb_file_per_table = on;
 set global innodb_file_format = `0`;
@@ -376,11 +376,11 @@ Warning	1478	InnoDB: ROW_FORMAT=DYNAMIC 
 Error	1005	Can't create table 'test.t7' (errno: 1478)
 create table t8 (id int primary key) engine = innodb row_format = compact;
 create table t9 (id int primary key) engine = innodb row_format = redundant;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
-table_schema	table_name	row_format
-test	t8	Compact
-test	t9	Redundant
+table_schema	table_name	row_format	data_length	index_length
+test	t8	Compact	16384	0
+test	t9	Redundant	16384	0
 drop table t8, t9;
 set global innodb_file_per_table=0;
 set global innodb_file_format=Antelope;

=== added file 'mysql-test/suite/innodb/r/innodb_bug59733.result'
--- a/mysql-test/suite/innodb/r/innodb_bug59733.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug59733.result	2011-08-15 09:18:34 +0000
@@ -0,0 +1,18 @@
+CREATE TABLE bug59733(a INT AUTO_INCREMENT PRIMARY KEY,b CHAR(1))ENGINE=InnoDB;
+INSERT INTO bug59733 VALUES(0,'x');
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+CREATE INDEX b ON bug59733 (b);
+DELETE FROM bug59733 WHERE (a%100)=0;
+DROP INDEX b ON bug59733;
+CREATE INDEX b ON bug59733 (b);
+DROP TABLE bug59733;

=== added file 'mysql-test/suite/innodb/r/innodb_corrupt_bit.result'
--- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result	2011-08-17 01:07:59 +0000
@@ -0,0 +1,81 @@
+set names utf8;
+CREATE TABLE corrupt_bit_test_ā(
+a INT AUTO_INCREMENT PRIMARY KEY,
+b CHAR(100),
+c INT,
+z INT,
+INDEX(b))
+ENGINE=InnoDB;
+INSERT INTO corrupt_bit_test_ā VALUES(0,'x',1, 1);
+CREATE UNIQUE INDEX idxā ON corrupt_bit_test_ā(c, b);
+CREATE UNIQUE INDEX idxē ON corrupt_bit_test_ā(z, b);
+SELECT * FROM corrupt_bit_test_ā;
+a	b	c	z
+1	x	1	1
+select @@unique_checks;
+@@unique_checks
+0
+select @@innodb_change_buffering_debug;
+@@innodb_change_buffering_debug
+1
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+400,z+400 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+800,z+800 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1600,z+1600 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+4000,z+4000 FROM corrupt_bit_test_ā;
+select count(*) from corrupt_bit_test_ā;
+count(*)
+1024
+CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c);
+INSERT INTO corrupt_bit_test_ā VALUES(13000,'x',1,1);
+CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z);
+check table corrupt_bit_test_ā;
+Table	Op	Msg_type	Msg_text
+test.corrupt_bit_test_ā	check	Warning	InnoDB: The B-tree of index "idxā" is corrupted.
+test.corrupt_bit_test_ā	check	Warning	InnoDB: The B-tree of index "idxē" is corrupted.
+test.corrupt_bit_test_
+ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it
+select z from corrupt_bit_test_ā;
+ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it
+show warnings;
+Level	Code	Message
+Warning	179	InnoDB: Index "idxē" for table "test/corrupt_bit_test_@1s" is marked as corrupted
+Error	1034	Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it
+insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
+select * from corrupt_bit_test_ā use index(primary) where a = 10001;
+a	b	c	z
+10001	a	20001	20001
+begin;
+insert into corrupt_bit_test_ā values (10002, "a", 20002, 20002);
+delete from corrupt_bit_test_ā where a = 10001;
+insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
+rollback;
+drop index idxā on corrupt_bit_test_ā;
+check table corrupt_bit_test_ā;
+Table	Op	Msg_type	Msg_text
+test.corrupt_bit_test_ā	check	Warning	InnoDB: Index "idxē" is marked as corrupted
+test.corrupt_bit_test_ā	check	error	Corrupt
+set names utf8;
+select z from corrupt_bit_test_ā;
+ERROR HY000: Incorrect key file for table 'corrupt_bit_test_t_ā;
+select z from corrupt_bit_test_ā limit 10;
+z
+20001
+1
+1
+2
+11
+12
+21
+22
+31
+32
+drop table corrupt_bit_test_ā;
+SET GLOBAL innodb_change_buffering_debug = 0;

=== modified file 'mysql-test/suite/innodb/t/innodb-zip.test'
--- a/mysql-test/suite/innodb/t/innodb-zip.test	2010-11-02 23:19:29 +0000
+++ b/mysql-test/suite/innodb/t/innodb-zip.test	2011-08-08 09:16:15 +0000
@@ -39,19 +39,19 @@ create table t13(a int primary key) engi
 row_format=compressed;
 create table t14(a int primary key) engine=innodb key_block_size=9;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 
 drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14;
 alter table t1 key_block_size=0;
 alter table t1 row_format=dynamic;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 alter table t1 row_format=compact;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 alter table t1 row_format=redundant;
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t1;
 
@@ -84,7 +84,7 @@ connection default;
 disconnect a;
 disconnect b;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t1,t2;
 
@@ -195,7 +195,7 @@ create table t9 (id int primary key) eng
 create table t10(id int primary key) engine = innodb row_format = compact;
 create table t11(id int primary key) engine = innodb row_format = redundant;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11;
 
@@ -221,7 +221,7 @@ show warnings;
 create table t5 (id int primary key) engine = innodb
 key_block_size = 8 row_format = default;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t1, t5;
 
@@ -241,7 +241,7 @@ create table t2 (id int primary key) eng
 key_block_size = 9 row_format = dynamic;
 show warnings;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 
 #test valid values with innodb_file_per_table unset
@@ -271,7 +271,7 @@ show warnings;
 create table t8 (id int primary key) engine = innodb row_format = compact;
 create table t9 (id int primary key) engine = innodb row_format = redundant;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t8, t9;
 
@@ -303,7 +303,7 @@ show warnings;
 create table t8 (id int primary key) engine = innodb row_format = compact;
 create table t9 (id int primary key) engine = innodb row_format = redundant;
 
-SELECT table_schema, table_name, row_format
+SELECT table_schema, table_name, row_format, data_length, index_length
 FROM information_schema.tables WHERE engine='innodb';
 drop table t8, t9;
 

=== added file 'mysql-test/suite/innodb/t/innodb_bug59733.test'
--- a/mysql-test/suite/innodb/t/innodb_bug59733.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug59733.test	2011-08-15 09:18:34 +0000
@@ -0,0 +1,53 @@
+#
+# Bug #59733 Possible deadlock when buffered changes are to be discarded
+# in buf_page_create
+#
+-- source include/have_innodb.inc
+
+-- disable_query_log
+# The flag innodb_change_buffering_debug is only available in debug builds.
+# It instructs InnoDB to try to evict pages from the buffer pool when
+# change buffering is possible, so that the change buffer will be used
+# whenever possible.
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug;
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = 1;
+-- enable_query_log
+
+CREATE TABLE bug59733(a INT AUTO_INCREMENT PRIMARY KEY,b CHAR(1))ENGINE=InnoDB;
+
+# Create enough rows for the table, so that the insert buffer will be
+# used. There must be multiple index pages, because changes to the
+# root page are never buffered.
+
+INSERT INTO bug59733 VALUES(0,'x');
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+INSERT INTO bug59733 SELECT 0,b FROM bug59733;
+
+# Create the secondary index for which changes will be buffered.
+CREATE INDEX b ON bug59733 (b);
+
+# This should be buffered, if innodb_change_buffering_debug = 1 is in effect.
+DELETE FROM bug59733 WHERE (a%100)=0;
+
+# Drop the index in order to get free pages with orphaned buffered changes.
+DROP INDEX b ON bug59733;
+
+# Create the index and attempt to reuse pages for which buffered changes exist.
+CREATE INDEX b ON bug59733 (b);
+
+DROP TABLE bug59733;
+
+-- disable_query_log
+-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = @innodb_change_buffering_debug_orig;

=== added file 'mysql-test/suite/innodb/t/innodb_corrupt_bit.test'
--- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test	2011-08-17 03:51:40 +0000
@@ -0,0 +1,120 @@
+#
+# Test for persistent corrupt bit for corrupted index and table
+#
+-- source include/have_innodb.inc
+
+# This test needs debug server
+--source include/have_debug.inc
+
+-- disable_query_log
+# This test setup is extracted from bug56680.test:
+# The flag innodb_change_buffering_debug is only available in debug builds.
+# It instructs InnoDB to try to evict pages from the buffer pool when
+# change buffering is possible, so that the change buffer will be used
+# whenever possible.
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug;
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = 1;
+
+# Turn off Unique Check to create corrupted index with dup key
+SET UNIQUE_CHECKS=0;
+
+-- enable_query_log
+
+set names utf8;
+
+CREATE TABLE corrupt_bit_test_ā(
+       a INT AUTO_INCREMENT PRIMARY KEY,
+       b CHAR(100),
+       c INT,
+       z INT,
+       INDEX(b))
+ENGINE=InnoDB;
+
+INSERT INTO corrupt_bit_test_ā VALUES(0,'x',1, 1);
+
+# This is the first unique index we intend to corrupt
+CREATE UNIQUE INDEX idxā ON corrupt_bit_test_ā(c, b);
+
+# This is the second unique index we intend to corrupt
+CREATE UNIQUE INDEX idxē ON corrupt_bit_test_ā(z, b);
+
+SELECT * FROM corrupt_bit_test_ā;
+
+select @@unique_checks;
+select @@innodb_change_buffering_debug;
+
+# Create enough rows for the table, so that the insert buffer will be
+# used for modifying the secondary index page. There must be multiple
+# index pages, because changes to the root page are never buffered.
+
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_T INTO corrupt_bit_test_ā SELECT 0,b,c+800,z+800 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1600,z+1600 FROM corrupt_bit_test_ā;
+INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+4000,z+4000 FROM corrupt_bit_test_ā;
+
+select count(*) from corrupt_bit_test_ā;
+
+CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c);
+
+# Create a dup key error on index "idxē" and "idxā" by inserting a dup value
+INSERT INTO corrupt_bit_test_ā VALUES(13000,'x',1,1);
+
+# creating an index should succeed even if other secondary indexes are corrupted
+CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z);
+
+# Check table will find the unique indexes corrupted
+# with dup key
+check table corrupt_bit_test_ā;
+
+# This selection intend to use the corrupted index. Expect to fail
+-- error ER_NOT_KEYFILE
+select c from corrupt_bit_test_ā;
+
+-- error ER_NOT_KEYFILE
+select z from corrupt_bit_test_ā;
+
+show warnings;
+
+# Since corrupted index is a secondary index, we only disable such
+# index and allow other DML to proceed
+insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
+
+# This does not use the corrupted index, expect to succeed
+select * from corrupt_bit_test_ā use index(primary) where a = 10001;
+
+# Some more DMLs
+begin;
+insert into corrupt_bit_test_ā values (10002, "a", 20002, 20002);
+delete from corrupt_bit_test_ā where a = 10001;
+insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
+rollback;
+
+# Drop one corrupted index before reboot
+drop index idxā on corrupt_bit_test_ā;
+
+check table corrupt_bit_test_ā;
+
+set names utf8;
+
+-- error ER_NOT_KEYFILE
+select z from corrupt_bit_test_ā;
+
+# Drop the corrupted index
+drop index idxē on corrupt_bit_test_ā;
+
+# Now select back to normal
+select z from corrupt_bit_test_ā limit 10;
+
+# Drop table
+drop table corrupt_bit_test_ā;
+
+-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = 0;

=== modified file 'mysql-test/suite/sys_vars/r/all_vars.result'
--- a/mysql-test/suite/sys_vars/r/all_vars.result	2011-05-31 09:12:32 +0000
+++ b/mysql-test/suite/sys_vars/r/all_vars.result	2011-08-17 03:51:40 +0000
@@ -11,13 +11,5 @@ There should be *no* long test name list
 select variable_name as `There should be *no* variables listed below:` from t2
 left join t1 on variable_name=test_name where test_name is null;
 There should be *no* variables listed below:
-INNODB_ROLLBACK_SEGMENTS
-INNODB_STATS_METHOD
-INNODB_FILE_FORMAT_MAX
-INNODB_LARGE_PREFIX
-INNODB_ROLLBACK_SEGMENTS
-INNODB_STATS_METHOD
-INNODB_FILE_FORMAT_MAX
-INNODB_LARGE_PREFIX
 drop table t1;
 drop table t2;

=== modified file 'mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result	2010-06-17 09:13:53 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_file_format_check_basic.result	2011-08-08 11:31:09 +0000
@@ -1,59 +1,80 @@
-SET @start_global_value = @@global.innodb_file_format_max;
+SET @start_global_value = @@global.innodb_file_format_check;
 SELECT @start_global_value;
 @start_global_value
-Antelope
-Valid values are 'Antelope' and 'Barracuda' 
-select @@global.innodb_file_format_max in ('Antelope', 'Barracuda');
-@@global.innodb_file_format_max in ('Antelope', 'Barracuda')
-1
-select @@global.innodb_file_format_max;
-@@global.innodb_file_format_max
-Antelope
-select @@session.innodb_file_format_max;
-ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable
-show global variables like 'innodb_file_format_max';
+1
+Valid values are 'ON' and 'OFF'
+SELECT @@global.innodb_file_format_check in (0, 1);
+@@global.innodb_file_format_check in (0, 1)
+1
+SELECT @@global.innodb_file_format_check;
+@@global.innodb_file_format_check
+1
+SELECT @@session.innodb_file_format_check;
+ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable
+SHOW global variables LIKE 'innodb_file_format_check';
 Variable_name	Value
-innodb_file_format_max	Antelope
-show session variables like 'innodb_file_format_max';
+innodb_file_format_check	ON
+SHOW session variables LIKE 'innodb_file_format_check';
 Variable_name	Value
-innodb_file_format_max	Antelope
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Antelope
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Antelope
-set global innodb_file_format_max='Antelope';
-select @@global.innodb_file_format_max;
-@@global.innodb_file_format_max
-Antelope
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Antelope
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Antelope
-set @@global.innodb_file_format_max='Barracuda';
-select @@global.innodb_file_format_max;
-@@global.innodb_file_format_max
-Barracuda
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Barracuda
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
-VARIABLE_NAME	VARIABLE_VALUE
-INNODB_FILE_FORMAT_MAX	Barracuda
-set session innodb_file_format_max='Salmon';
-ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL
-set @@session.innodb_file_format_max='Salmon';
-ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL
-set global innodb_file_format_max=1.1;
-ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max'
-set global innodb_file_format_max=1e1;
-ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max'
-set global innodb_file_format_max='Salmon';
-ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'Salmon'
-SET @@global.innodb_file_format_max = @start_global_value;
-SELECT @@global.innodb_file_format_max;
-@@global.innodb_file_format_max
-Antelope
+innodb_file_format_check	ON
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_check';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_CHECK	ON
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_check';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_CHECK	ON
+SET @@global.innodb_file_format_check='Off';
+ERROR HY000: Variable 'innodb_file_format_check' is a read only variable
+Expected error 'Read only variable'
+SET @@global.innodb_file_format_check=1;
+ERROR HY000: Variable 'innodb_file_format_check' is a read only variable
+Expected error 'Read only variable'
+SET @@global.innodb_file_format_check=0;
+ERROR HY000: Variable 'innodb_file_format_check' is a read only variable
+Expected error 'Read only variable'
+SET @@global.innodb_file_format_check='On';
+ERROR HY000: Variable 'innodb_file_format_check' is a read only variable
+Expected error 'Read only variable'
+SET session innodb_large_prefix='OFF';
+ERROR HY000: Variable 'innodb_large_prefix' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@session.innodb_stats_on_metadata='ON';
+ERROR HY000: Variable 'innodb_stats_on_metadata' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT IF(@@GLOBAL.innodb_file_format_check, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_file_format_check';
+IF(@@GLOBAL.innodb_file_format_check, "ON", "OFF") = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.innodb_file_format_check);
+COUNT(@@GLOBAL.innodb_file_format_check)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_file_format_check';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+SELECT @@innodb_file_format_check = @@GLOBAL.innodb_file_format_check;
+@@innodb_file_format_check = @@GLOBAL.innodb_file_format_check
+1
+1 Expected
+SELECT COUNT(@@innodb_file_format_check);
+COUNT(@@innodb_file_format_check)
+1
+1 Expected
+SELECT COUNT(@@local.innodb_file_format_check);
+ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@SESSION.innodb_file_format_check);
+ERROR HY000: Variable 'innodb_file_format_check' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@GLOBAL.innodb_file_format_check);
+COUNT(@@GLOBAL.innodb_file_format_check)
+1
+1 Expected
+SELECT innodb_file_format_check = @@SESSION.innodb_file_format_check;
+ERROR 42S22: Unknown column 'innodb_file_format_check' in 'field list'
+Expected error 'Readonly variable'

=== added file 'mysql-test/suite/sys_vars/r/innodb_file_format_max_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_file_format_max_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_file_format_max_basic.result	2011-08-08 11:31:09 +0000
@@ -0,0 +1,65 @@
+SET @start_global_value = @@global.innodb_file_format_max;
+SELECT @start_global_value;
+@start_global_value
+Antelope
+Valid values are 'Antelope' and 'Barracuda' 
+SELECT @@global.innodb_file_format_max in ('Antelope', 'Barracuda');
+@@global.innodb_file_format_max in ('Antelope', 'Barracuda')
+1
+SELECT @@global.innodb_file_format_max;
+@@global.innodb_file_format_max
+Antelope
+SELECT @@session.innodb_file_format_max;
+ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable
+SHOW global variables LIKE 'innodb_file_format_max';
+Variable_name	Value
+innodb_file_format_max	Antelope
+SHOW session variables LIKE 'innodb_file_format_max';
+Variable_name	Value
+innodb_file_format_max	Antelope
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Antelope
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Antelope
+SET global innodb_file_format_max='Antelope';
+SELECT @@global.innodb_file_format_max;
+@@global.innodb_file_format_max
+Antelope
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Antelope
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Antelope
+SET @@global.innodb_file_format_max='Barracuda';
+SELECT @@global.innodb_file_format_max;
+@@global.innodb_file_format_max
+Barracuda
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Barracuda
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_max';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FILE_FORMAT_MAX	Barracuda
+SET session innodb_file_format_max='Salmon';
+ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@session.innodb_file_format_max='Salmon';
+ERROR HY000: Variable 'innodb_file_format_max' is a GLOBAL variable and should be set with SET GLOBAL
+SET global innodb_file_format_max=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max'
+SET global innodb_file_format_max=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_file_format_max'
+SET global innodb_file_format_max='Salmon';
+ERROR 42000: Variable 'innodb_file_format_max' can't be set to the value of 'Salmon'
+SET @@global.innodb_file_format_max = @start_global_value;
+SELECT @@global.innodb_file_format_max;
+@@global.innodb_file_format_max
+Antelope

=== modified file 'mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result	2009-08-07 20:04:53 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_file_per_table_basic.result	2011-08-16 10:36:34 +0000
@@ -1,13 +1,29 @@
+SET @start_global_value = @@global.innodb_file_per_table;
+SELECT @start_global_value;
+@start_global_value
+0
 '#---------------------BS_STVARS_028_01----------------------#'
 SELECT COUNT(@@GLOBAL.innodb_file_per_table);
 COUNT(@@GLOBAL.innodb_file_per_table)
 1
 1 Expected
 '#---------------------BS_STVARS_028_02----------------------#'
-SELECT COUNT(@@GLOBAL.innodb_file_per_table);
-COUNT(@@GLOBAL.innodb_file_per_table)
+SET @@global.innodb_file_per_table = 0;
+SELECT @@global.innodb_file_per_table;
+@@global.innodb_file_per_table
+0
+SET @@global.innodb_file_per_table ='On' ;
+SELECT @@global.innodb_file_per_table;
+@@global.innodb_file_per_table
+1
+SET @@global.innodb_file_per_table ='Off' ;
+SELECT @@global.innodb_file_per_table;
+@@global.innodb_file_per_table
+0
+SET @@global.innodb_file_per_table = 1;
+SELECT @@global.innodb_file_per_table;
+@@global.innodb_file_per_table
 1
-1 Expected
 '#---------------------BS_STVARS_028_03----------------------#'
 SELECT IF(@@GLOBAL.innodb_file_per_table,'ON','OFF') = VARIABLE_VALUE
 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -47,4 +63,7 @@ COUNT(@@GLOBAL.innodb_file_per_table)
 1 Expected
 SELECT innodb_file_per_table = @@SESSION.innodb_file_per_table;
 ERROR 42S22: Unknown column 'innodb_file_per_table' in 'field list'
-Expected error 'Readonly variable'
+SET @@global.innodb_file_per_table = @start_global_value;
+SELECT @@global.innodb_file_per_table;
+@@global.innodb_file_per_table
+0

=== added file 'mysql-test/suite/sys_vars/r/innodb_force_load_corrupted_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_force_load_corrupted_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_force_load_corrupted_basic.result	2011-08-17 03:51:40 +0000
@@ -0,0 +1,53 @@
+'#---------------------BS_STVARS_031_01----------------------#'
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+COUNT(@@GLOBAL.innodb_force_load_corrupted)
+1
+1 Expected
+'#---------------------BS_STVARS_031_02----------------------#'
+SET @@GLOBAL.innodb_force_load_corrupted=1;
+ERROR HY000: Variable 'innodb_force_load_corrupted' is a read only variable
+Expected error 'Read only variable'
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+COUNT(@@GLOBAL.innodb_force_load_corrupted)
+1
+1 Expected
+'#---------------------BS_STVARS_031_03----------------------#'
+SELECT IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_force_load_corrupted';
+IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+COUNT(@@GLOBAL.innodb_force_load_corrupted)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+WHERE VARIABLE_NAME='innodb_force_load_corrupted';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+'#---------------------BS_STVARS_031_04----------------------#'
+SELECT @@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted;
+@@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted
+1
+1 Expected
+'#---------------------BS_STVARS_031_05----------------------#'
+SELECT COUNT(@@innodb_force_load_corrupted);
+COUNT(@@innodb_force_load_corrupted)
+1
+1 Expected
+SELECT COUNT(@@local.innodb_force_load_corrupted);
+ERROR HY000: Variable 'innodb_force_load_corrupted' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@SESSION.innodb_force_load_corrupted);
+ERROR HY000: Variable 'innodb_force_load_corrupted' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+COUNT(@@GLOBAL.innodb_force_load_corrupted)
+1
+1 Expected
+SELECT innodb_force_load_corrupted = @@SESSION.innodb_force_load_corrupted;
+ERROR 42S22: Unknown column 'innodb_force_load_corrupted' in 'field list'
+Expected error 'Readonly variable'

=== added file 'mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result	2011-08-17 03:51:40 +0000
@@ -0,0 +1,92 @@
+SET @start_global_value = @@global.innodb_large_prefix;
+SELECT @start_global_value;
+@start_global_value
+0
+Valid values are 'ON' and 'OFF' 
+select @@global.innodb_large_prefix in (0, 1);
+@@global.innodb_large_prefix in (0, 1)
+1
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+0
+select @@session.innodb_large_prefix;
+ERROR HY000: Variable 'innodb_large_prefix' is a GLOBAL variable
+show global variables like 'innodb_large_prefix';
+Variable_name	Value
+innodb_large_prefix	OFF
+show session variables like 'innodb_large_prefix';
+Variable_name	Value
+innodb_large_prefix	OFF
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+set global innodb_large_prefix='OFF';
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+0
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+set @@global.innodb_large_prefix=1;
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+1
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+set global innodb_large_prefix=0;
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+0
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	OFF
+set @@global.innodb_large_prefix='ON';
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+1
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+set session innodb_large_prefix='OFF';
+ERROR HY000: Variable 'innodb_large_prefix' is a GLOBAL variable and should be set with SET GLOBAL
+set @@session.innodb_large_prefix='ON';
+ERROR HY000: Variable 'innodb_large_prefix' is a GLOBAL variable and should be set with SET GLOBAL
+set global innodb_large_prefix=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_large_prefix'
+set global innodb_large_prefix=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_large_prefix'
+set global innodb_large_prefix=2;
+ERROR 42000: Variable 'innodb_large_prefix' can't be set to the value of '2'
+NOTE: The following should fail with ER_WRONG_VALUE_FOR_VAR (BUG#50643)
+set global innodb_large_prefix=-3;
+select @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+1
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_LARGE_PREFIX	ON
+set global innodb_large_prefix='AUTO';
+ERROR 42000: Variable 'innodb_large_prefix' can't be set to the value of 'AUTO'
+SET @@global.innodb_large_prefix = @start_global_value;
+SELECT @@global.innodb_large_prefix;
+@@global.innodb_large_prefix
+0

=== modified file 'mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result	2009-08-07 20:04:53 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result	2011-08-16 10:36:34 +0000
@@ -1,13 +1,21 @@
+SET @start_global_value=@@global.innodb_lock_wait_timeout;
+SELECT @start_global_value;
+@start_global_value
+50
 '#---------------------BS_STVARS_032_01----------------------#'
 SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout);
 COUNT(@@GLOBAL.innodb_lock_wait_timeout)
 1
 1 Expected
 '#---------------------BS_STVARS_032_02----------------------#'
-SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout);
-COUNT(@@GLOBAL.innodb_lock_wait_timeout)
-1
-1 Expected
+SET global innodb_lock_wait_timeout=60;
+SELECT @@global.innodb_lock_wait_timeout;
+@@global.innodb_lock_wait_timeout
+60
+SET session innodb_lock_wait_timeout=60;
+SELECT @@session.innodb_lock_wait_timeout;
+@@session.innodb_lock_wait_timeout
+60
 '#---------------------BS_STVARS_032_03----------------------#'
 SELECT @@GLOBAL.innodb_lock_wait_timeout = VARIABLE_VALUE
 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -47,4 +55,7 @@ COUNT(@@GLOBAL.innodb_lock_wait_timeout)
 1 Expected
 SELECT innodb_lock_wait_timeout = @@SESSION.innodb_lock_wait_timeout;
 ERROR 42S22: Unknown column 'innodb_lock_wait_timeout' in 'field list'
-Expected error 'Readonly variable'
+SET @@global.innodb_lock_wait_timeout = @start_global_value;
+SELECT @@global.innodb_lock_wait_timeout;
+@@global.innodb_lock_wait_timeout
+50

=== added file 'mysql-test/suite/sys_vars/r/innodb_rollback_segments_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_rollback_segments_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_rollback_segments_basic.result	2011-08-08 11:31:09 +0000
@@ -0,0 +1,64 @@
+SET @start_global_value = @@global.innodb_rollback_segments;
+SELECT @start_global_value;
+@start_global_value
+128
+Valid values are zero or above
+SELECT @@global.innodb_rollback_segments >=0;
+@@global.innodb_rollback_segments >=0
+1
+SELECT @@global.innodb_rollback_segments <=128;
+@@global.innodb_rollback_segments <=128
+1
+SELECT @@global.innodb_rollback_segments;
+@@global.innodb_rollback_segments
+128
+SELECT @@session.innodb_rollback_segments;
+ERROR HY000: Variable 'innodb_rollback_segments' is a GLOBAL variable
+SHOW global variables LIKE 'innodb_rollback_segments';
+Variable_name	Value
+innodb_rollback_segments	128
+SHOW session variables LIKE 'innodb_rollback_segments';
+Variable_name	Value
+innodb_rollback_segments	128
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_ROLLBACK_SEGMENTS	128
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_rollback_segments';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_ROLLBACK_SEGMENTS	128
+SET global innodb_rollback_segments=100;
+SELECT @@global.innodb_rollback_segments;
+@@global.innodb_rollback_segments
+100
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_ROLLBACK_SEGMENTS	100
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_rollback_segments';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_ROLLBACK_SEGMENTS	100
+SET session innodb_rollback_segments=1;
+ERROR HY000: Variable 'innodb_rollback_segments' is a GLOBAL variable and should be set with SET GLOBAL
+SET global innodb_rollback_segments=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_rollback_segments'
+SET global innodb_rollback_segments=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_rollback_segments'
+SET global innodb_rollback_segments="foo";
+ERROR 42000: Incorrect argument type to variable 'innodb_rollback_segments'
+SET global innodb_rollback_segments=-7;
+Warnings:
+Warning	1292	Truncated incorrect innodb_rollback_segments value: '-7'
+SELECT @@global.innodb_rollback_segments;
+@@global.innodb_rollback_segments
+1
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_ROLLBACK_SEGMENTS	1
+SET @@global.innodb_rollback_segments = @start_global_value;
+SELECT @@global.innodb_rollback_segments;
+@@global.innodb_rollback_segments
+128

=== added file 'mysql-test/suite/sys_vars/r/innodb_stats_method_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_stats_method_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_stats_method_basic.result	2011-08-08 11:31:09 +0000
@@ -0,0 +1,83 @@
+SET @start_global_value = @@global.innodb_stats_method;
+SELECT @start_global_value;
+@start_global_value
+nulls_equal
+Valid values are 'nulls_equal', 'nulls_unequal', 'nulls_ignored'
+SELECT @@global.innodb_stats_method in ('nulls_equal', 'nulls_unequal', 
+'nulls_ignored');
+@@global.innodb_stats_method in ('nulls_equal', 'nulls_unequal', 
+'nulls_ignored')
+1
+SELECT @@global.innodb_stats_method;
+@@global.innodb_stats_method
+nulls_equal
+SELECT @@session.innodb_stats_method;
+ERROR HY000: Variable 'innodb_stats_method' is a GLOBAL variable
+SHOW global variables LIKE 'innodb_stats_method';
+Variable_name	Value
+innodb_stats_method	nulls_equal
+SHOW session variables LIKE 'innodb_stats_method';
+Variable_name	Value
+innodb_stats_method	nulls_equal
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_equal
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_equal
+SET global innodb_stats_method='nulls_equal';
+SELECT @@global.innodb_stats_method;
+@@global.innodb_stats_method
+nulls_equal
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_equal
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_equal
+SET @@global.innodb_stats_method='nulls_unequal';
+SELECT @@global.innodb_stats_method;
+@@global.innodb_stats_method
+nulls_unequal
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_unequal
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_unequal
+SET global innodb_stats_method=2;
+SELECT @@global.innodb_stats_method;
+@@global.innodb_stats_method
+nulls_ignored
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_ignored
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_STATS_METHOD	nulls_ignored
+SET session innodb_stats_method='nulls_equal';
+ERROR HY000: Variable 'innodb_stats_method' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@session.innodb_stats_method='nulls_ignored';
+ERROR HY000: Variable 'innodb_stats_method' is a GLOBAL variable and should be set with SET GLOBAL
+SET global innodb_stats_method=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_stats_method'
+SET global innodb_stats_method=4;
+ERROR 42000: Variable 'innodb_stats_method' can't be set to the value of '4'
+SET global innodb_stats_method=-2;
+ERROR 42000: Variable 'innodb_stats_method' can't be set to the value of '-2'
+SET global innodb_stats_method=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_stats_method'
+SET global innodb_stats_method='some';
+ERROR 42000: Variable 'innodb_stats_method' can't be set to the value of 'some'
+SET @@global.innodb_stats_method = @start_global_value;
+SELECT @@global.innodb_stats_method;
+@@global.innodb_stats_method
+nulls_equal

=== modified file 'mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_basic.test	2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_autoinc_lock_mode_basic.test	2011-08-16 10:36:34 +0000
@@ -1,8 +1,7 @@
 ################# mysql-test\t\innodb_autoinc_lock_mode_basic.test ############
 #                                                                             #
 # Variable Name: innodb_autoinc_lock_mode                                     #
-# Scope: GLOBAL                                                               #
-# Access Type: Dynamic                                                        #
+# Access Type: Static                                                         #
 # Data Type: Numeric                                                          #
 # Default Value: 1                                                            #
 # Range: 0,1,2                                                                #

=== modified file 'mysql-test/suite/sys_vars/t/innodb_fast_shutdown_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_fast_shutdown_basic.test	2010-07-15 11:13:30 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_fast_shutdown_basic.test	2011-08-16 10:36:34 +0000
@@ -3,9 +3,9 @@
 # Variable Name: innodb_fast_shutdown                                         #
 # Scope: GLOBAL                                                               #
 # Access Type: Dynamic                                                        #
-# Data Type: boolean                                                          #
+# Data Type: numeric                                                          #
 # Default Value: 1                                                            #
-# Valid Values: 0,1                                                           #
+# Valid Values: 0,1,2                                                           #
 #                                                                             #
 #                                                                             #
 # Creation Date: 2008-02-20                                                   #

=== modified file 'mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test	2010-06-17 20:51:35 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_file_format_check_basic.test	2011-08-08 11:31:09 +0000
@@ -1,55 +1,95 @@
-
-
-# 2010-01-25 - Added
 #
+# 2011-08-02 - Added
+#
+
 --source include/not_embedded.inc
 --source include/have_innodb.inc
 
-SET @start_global_value = @@global.innodb_file_format_max;
+SET @start_global_value = @@global.innodb_file_format_check;
 SELECT @start_global_value;
 
 #
 # exists as global only
 #
---echo Valid values are 'Antelope' and 'Barracuda' 
-select @@global.innodb_file_format_max in ('Antelope', 'Barracuda');
-select @@global.innodb_file_format_max;
+--echo  Valid values are 'ON' and 'OFF'
+SELECT @@global.innodb_file_format_check in (0, 1);
+SELECT @@global.innodb_file_format_check;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_file_format_check;
+SHOW global variables LIKE 'innodb_file_format_check';
+SHOW session variables LIKE 'innodb_file_format_check';
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_check';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_check';
+
+#
+# show that it's read only
+#
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.innodb_file_format_check='Off';
+--echo Expected error 'Read only variable'
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.innodb_file_format_check=1; 
+--echo Expected error 'Read only variable'
+
 --error ER_INCORRECT_GLOBAL_LOCAL_VAR
-select @@session.innodb_file_format_max;
-show global variables like 'innodb_file_format_max';
-show session variables like 'innodb_file_format_max';
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
-
-#
-# show that it's writable
-#
-set global innodb_file_format_max='Antelope';
-select @@global.innodb_file_format_max;
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
-set @@global.innodb_file_format_max='Barracuda';
-select @@global.innodb_file_format_max;
-select * from information_schema.global_variables where variable_name='innodb_file_format_max';
-select * from information_schema.session_variables where variable_name='innodb_file_format_max';
+SET @@global.innodb_file_format_check=0;
+--echo Expected error 'Read only variable'
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@global.innodb_file_format_check='On';
+--echo Expected error 'Read only variable'
+
 --error ER_GLOBAL_VARIABLE
-set session innodb_file_format_max='Salmon';
+SET session innodb_large_prefix='OFF';
 --error ER_GLOBAL_VARIABLE
-set @@session.innodb_file_format_max='Salmon';
+SET @@session.innodb_stats_on_metadata='ON';
 
 #
-# incorrect types
+# Check if the value in GLOBAL Table matches value in variable 
 #
---error ER_WRONG_TYPE_FOR_VAR
-set global innodb_file_format_max=1.1;
---error ER_WRONG_TYPE_FOR_VAR
-set global innodb_file_format_max=1e1;
---error ER_WRONG_VALUE_FOR_VAR
-set global innodb_file_format_max='Salmon';
+
+SELECT IF(@@GLOBAL.innodb_file_format_check, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_file_format_check';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.innodb_file_format_check);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_file_format_check';
+--echo 1 Expected
 
 #
-# Cleanup
+# Check if accessing variable with and without GLOBAL point to same variable
 #
+SELECT @@innodb_file_format_check = @@GLOBAL.innodb_file_format_check;
+--echo 1 Expected
+
+#
+# Check if innodb_doublewrite can be accessed with and without @@ sign 
+#
+
+SELECT COUNT(@@innodb_file_format_check);
+--echo 1 Expected
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.innodb_file_format_check);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.innodb_file_format_check);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+SELECT COUNT(@@GLOBAL.innodb_file_format_check);
+--echo 1 Expected
 
-SET @@global.innodb_file_format_max = @start_global_value;
-SELECT @@global.innodb_file_format_max;
+--Error ER_BAD_FIELD_ERROR
+SELECT innodb_file_format_check = @@SESSION.innodb_file_format_check;
+--echo Expected error 'Readonly variable'

=== added file 'mysql-test/suite/sys_vars/t/innodb_file_format_max_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_file_format_max_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_file_format_max_basic.test	2011-08-08 11:31:09 +0000
@@ -0,0 +1,60 @@
+#
+# 2011-08-02 - Added
+#
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+
+SET @start_global_value = @@global.innodb_file_format_max;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+--echo Valid values are 'Antelope' and 'Barracuda' 
+SELECT @@global.innodb_file_format_max in ('Antelope', 'Barracuda');
+SELECT @@global.innodb_file_format_max;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_file_format_max;
+SHOW global variables LIKE 'innodb_file_format_max';
+SHOW session variables LIKE 'innodb_file_format_max';
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+SELECT * FROM information_schema.session_variables
+WHERE variable_name='innodb_file_format_max';
+
+#
+# show that it's writable
+#
+SET global innodb_file_format_max='Antelope';
+SELECT @@global.innodb_file_format_max;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_max';
+SET @@global.innodb_file_format_max='Barracuda';
+SELECT @@global.innodb_file_format_max;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_file_format_max';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_file_format_max';
+--error ER_GLOBAL_VARIABLE
+SET session innodb_file_format_max='Salmon';
+--error ER_GLOBAL_VARIABLE
+SET @@session.innodb_file_format_max='Salmon';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_file_format_max=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_file_format_max=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_file_format_max='Salmon';
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_file_format_max = @start_global_value;
+SELECT @@global.innodb_file_format_max;

=== modified file 'mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test	2009-08-07 20:04:53 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_file_per_table_basic.test	2011-08-16 10:36:34 +0000
@@ -4,7 +4,7 @@
 #                                                                             #
 # Variable Name: innodb_file_per_table                                        #
 # Scope: Global                                                               #
-# Access Type: Static                                                         #
+# Access Type: Dynamic                                                        #
 # Data Type: boolean                                                          #
 #                                                                             #
 #                                                                             #
@@ -24,6 +24,10 @@
 
 --source include/have_innodb.inc
 
+SET @start_global_value = @@global.innodb_file_per_table;
+SELECT @start_global_value;
+
+
 --echo '#---------------------BS_STVARS_028_01----------------------#'
 ####################################################################
 #   Displaying default value                                       #
@@ -37,11 +41,17 @@ SELECT COUNT(@@GLOBAL.innodb_file_per_ta
 #   Check if Value can set                                         #
 ####################################################################
 
-SELECT COUNT(@@GLOBAL.innodb_file_per_table);
---echo 1 Expected
+SET @@global.innodb_file_per_table = 0;
+SELECT @@global.innodb_file_per_table;
 
+SET @@global.innodb_file_per_table ='On' ;
+SELECT @@global.innodb_file_per_table;
 
+SET @@global.innodb_file_per_table ='Off' ;
+SELECT @@global.innodb_file_per_table;
 
+SET @@global.innodb_file_per_table = 1;
+SELECT @@global.innodb_file_per_table;
 
 --echo '#---------------------BS_STVARS_028_03----------------------#'
 #################################################################
@@ -93,6 +103,10 @@ SELECT COUNT(@@GLOBAL.innodb_file_per_ta
 
 --Error ER_BAD_FIELD_ERROR
 SELECT innodb_file_per_table = @@SESSION.innodb_file_per_table;
---echo Expected error 'Readonly variable'
 
+#
+# Cleanup
+#
 
+SET @@global.innodb_file_per_table = @start_global_value;
+SELECT @@global.innodb_file_per_table;

=== added file 'mysql-test/suite/sys_vars/t/innodb_force_load_corrupted_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_force_load_corrupted_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_force_load_corrupted_basic.test	2011-08-17 03:51:40 +0000
@@ -0,0 +1,102 @@
+
+
+################## mysql-test\t\innodb_force_load_corrupted_basic.test #####
+#                                                                             #
+# Variable Name: innodb_force_load_corrupted                               #
+# Scope: Global                                                               #
+# Access Type: Static                                                         #
+# Data Type: boolean                                                          #
+#                                                                             #
+#                                                                             #
+# Creation Date: 2008-02-07                                                   #
+# Author : Sharique Abdullah                                                      #
+#                                                                             #
+#                                                                             #
+# Description:Test Cases of Dynamic System Variable innodb_force_load_corrupted#
+#             that checks the behavior of this variable in the following ways #
+#              * Value Check                                                  #
+#              * Scope Check                                                  #
+#                                                                             #
+# Reference: http://dev.mysql.com/doc/refman/5.1/en/                          #
+#  server-system-variables.html                                               #
+#                                                                             #
+###############################################################################
+
+--source include/have_innodb.inc
+
+--echo '#---------------------BS_STVARS_031_01----------------------#'
+####################################################################
+#   Displaying default value                                       #
+####################################################################
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_031_02----------------------#'
+####################################################################
+#   Check if Value can set                                         #
+####################################################################
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.innodb_force_load_corrupted=1;
+--echo Expected error 'Read only variable'
+
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+--echo 1 Expected
+
+
+
+
+--echo '#---------------------BS_STVARS_031_03----------------------#'
+#################################################################
+# Check if the value in GLOBAL Table matches value in variable  #
+#################################################################
+
+SELECT IF(@@GLOBAL.innodb_force_load_corrupted, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_force_load_corrupted';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+WHERE VARIABLE_NAME='innodb_force_load_corrupted';
+--echo 1 Expected
+
+
+
+--echo '#---------------------BS_STVARS_031_04----------------------#'
+################################################################################
+#  Check if accessing variable with and without GLOBAL point to same variable  #
+################################################################################
+SELECT @@innodb_force_load_corrupted = @@GLOBAL.innodb_force_load_corrupted;
+--echo 1 Expected
+
+
+
+--echo '#---------------------BS_STVARS_031_05----------------------#'
+################################################################################
+#   Check if innodb_force_load_corrupted can be accessed with and without @@ sign #
+################################################################################
+
+SELECT COUNT(@@innodb_force_load_corrupted);
+--echo 1 Expected
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.innodb_force_load_corrupted);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.innodb_force_load_corrupted);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+SELECT COUNT(@@GLOBAL.innodb_force_load_corrupted);
+--echo 1 Expected
+
+--Error ER_BAD_FIELD_ERROR
+SELECT innodb_force_load_corrupted = @@SESSION.innodb_force_load_corrupted;
+--echo Expected error 'Readonly variable'
+
+

=== modified file 'mysql-test/suite/sys_vars/t/innodb_io_capacity_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_io_capacity_basic.test	2010-01-29 06:33:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_io_capacity_basic.test	2011-08-16 10:36:34 +0000
@@ -54,5 +54,9 @@ select * from information_schema.global_
 set global innodb_io_capacity=100;
 select @@global.innodb_io_capacity;
 
+#
+# cleanup
+#
+
 SET @@global.innodb_io_capacity = @start_global_value;
 SELECT @@global.innodb_io_capacity;

=== added file 'mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test	2011-08-17 03:51:40 +0000
@@ -0,0 +1,70 @@
+
+
+# 2010-01-25 - Added
+#
+
+--source include/have_innodb.inc
+
+SET @start_global_value = @@global.innodb_large_prefix;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+--echo Valid values are 'ON' and 'OFF' 
+select @@global.innodb_large_prefix in (0, 1);
+select @@global.innodb_large_prefix;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_large_prefix;
+show global variables like 'innodb_large_prefix';
+show session variables like 'innodb_large_prefix';
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+
+#
+# show that it's writable
+#
+set global innodb_large_prefix='OFF';
+select @@global.innodb_large_prefix;
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+set @@global.innodb_large_prefix=1;
+select @@global.innodb_large_prefix;
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+set global innodb_large_prefix=0;
+select @@global.innodb_large_prefix;
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+set @@global.innodb_large_prefix='ON';
+select @@global.innodb_large_prefix;
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+--error ER_GLOBAL_VARIABLE
+set session innodb_large_prefix='OFF';
+--error ER_GLOBAL_VARIABLE
+set @@session.innodb_large_prefix='ON';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_large_prefix=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_large_prefix=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_large_prefix=2;
+--echo NOTE: The following should fail with ER_WRONG_VALUE_FOR_VAR (BUG#50643)
+set global innodb_large_prefix=-3;
+select @@global.innodb_large_prefix;
+select * from information_schema.global_variables where variable_name='innodb_large_prefix';
+select * from information_schema.session_variables where variable_name='innodb_large_prefix';
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_large_prefix='AUTO';
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_large_prefix = @start_global_value;
+SELECT @@global.innodb_large_prefix;

=== modified file 'mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test	2009-08-07 20:04:53 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_lock_wait_timeout_basic.test	2011-08-16 10:36:34 +0000
@@ -3,13 +3,13 @@
 ################## mysql-test\t\innodb_lock_wait_timeout_basic.test ###########
 #                                                                             #
 # Variable Name: innodb_lock_wait_timeout                                     #
-# Scope: Global                                                               #
-# Access Type: Static                                                         #
+# Scope: Global , Session                                                     #
+# Access Type: Dynamic                                                        #
 # Data Type: numeric                                                          #
 #                                                                             #
 #                                                                             #
 # Creation Date: 2008-02-07                                                   #
-# Author : Sharique Abdullah                                                      #
+# Author : Sharique Abdullah                                                  #
 #                                                                             #
 #                                                                             #
 # Description:Test Cases of Dynamic System Variable innodb_lock_wait_timeout  #
@@ -24,6 +24,9 @@
 
 --source include/have_innodb.inc
 
+SET @start_global_value=@@global.innodb_lock_wait_timeout;
+SELECT @start_global_value;
+
 --echo '#---------------------BS_STVARS_032_01----------------------#'
 ####################################################################
 #   Displaying default value                                       #
@@ -37,11 +40,10 @@ SELECT COUNT(@@GLOBAL.innodb_lock_wait_t
 #   Check if Value can set                                         #
 ####################################################################
 
-SELECT COUNT(@@GLOBAL.innodb_lock_wait_timeout);
---echo 1 Expected
-
-
-
+SET global innodb_lock_wait_timeout=60;
+SELECT @@global.innodb_lock_wait_timeout;
+SET session innodb_lock_wait_timeout=60;
+SELECT @@session.innodb_lock_wait_timeout;
 
 --echo '#---------------------BS_STVARS_032_03----------------------#'
 #################################################################
@@ -89,6 +91,10 @@ SELECT COUNT(@@GLOBAL.innodb_lock_wait_t
 
 --Error ER_BAD_FIELD_ERROR
 SELECT innodb_lock_wait_timeout = @@SESSION.innodb_lock_wait_timeout;
---echo Expected error 'Readonly variable'
 
+#
+# Cleanup
+#
 
+SET @@global.innodb_lock_wait_timeout = @start_global_value;
+SELECT @@global.innodb_lock_wait_timeout;

=== modified file 'mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test	2009-02-17 12:24:09 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_max_dirty_pages_pct_basic.test	2011-08-16 10:36:34 +0000
@@ -4,8 +4,8 @@
 # Scope: GLOBAL                                                               #
 # Access Type: Dynamic                                                        #
 # Data Type: Numeric                                                          #
-# Default Value: 90                                                           #
-# Range: 0-1000                                                               #
+# Default Value: 75                                                           #
+# Range: 0-99                                                                 #
 #                                                                             #
 #                                                                             #
 # Creation Date: 2008-02-07                                                   #

=== added file 'mysql-test/suite/sys_vars/t/innodb_rollback_segments_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_rollback_segments_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_rollback_segments_basic.test	2011-08-08 11:31:09 +0000
@@ -0,0 +1,58 @@
+#
+#  2011-08-01  Added
+#
+
+--source include/have_innodb.inc
+
+SET @start_global_value = @@global.innodb_rollback_segments;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+--echo Valid values are zero or above
+SELECT @@global.innodb_rollback_segments >=0;
+SELECT @@global.innodb_rollback_segments <=128;
+SELECT @@global.innodb_rollback_segments;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_rollback_segments;
+SHOW global variables LIKE 'innodb_rollback_segments';
+SHOW session variables LIKE 'innodb_rollback_segments';
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_rollback_segments';
+
+#
+# show that it's writable
+#
+SET global innodb_rollback_segments=100;
+SELECT @@global.innodb_rollback_segments;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_rollback_segments';
+--error ER_GLOBAL_VARIABLE
+SET session innodb_rollback_segments=1;
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_rollback_segments=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_rollback_segments=1e1;
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_rollback_segments="foo";
+SET global innodb_rollback_segments=-7;
+SELECT @@global.innodb_rollback_segments;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_rollback_segments';
+
+#
+# cleanup
+#
+
+SET @@global.innodb_rollback_segments = @start_global_value;
+SELECT @@global.innodb_rollback_segments;

=== added file 'mysql-test/suite/sys_vars/t/innodb_stats_method_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_stats_method_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_stats_method_basic.test	2011-08-08 11:31:09 +0000
@@ -0,0 +1,72 @@
+#
+# 2011-08-05 - Added
+#
+
+--source include/have_innodb.inc
+
+SET @start_global_value = @@global.innodb_stats_method;
+SELECT @start_global_value;
+
+#
+# exists as global only 
+#
+--echo Valid values are 'nulls_equal', 'nulls_unequal', 'nulls_ignored'
+SELECT @@global.innodb_stats_method in ('nulls_equal', 'nulls_unequal', 
+'nulls_ignored');
+SELECT @@global.innodb_stats_method;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_stats_method;
+SHOW global variables LIKE 'innodb_stats_method';
+SHOW session variables LIKE 'innodb_stats_method';
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+
+#
+# show that it's writable
+#
+SET global innodb_stats_method='nulls_equal';
+SELECT @@global.innodb_stats_method;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+SET @@global.innodb_stats_method='nulls_unequal';
+SELECT @@global.innodb_stats_method;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+SET global innodb_stats_method=2;
+SELECT @@global.innodb_stats_method;
+SELECT * FROM information_schema.global_variables 
+WHERE variable_name='innodb_stats_method';
+SELECT * FROM information_schema.session_variables 
+WHERE variable_name='innodb_stats_method';
+
+--error ER_GLOBAL_VARIABLE
+SET session innodb_stats_method='nulls_equal';
+--error ER_GLOBAL_VARIABLE
+SET @@session.innodb_stats_method='nulls_ignored';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_stats_method=1.1;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_stats_method=4;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_stats_method=-2;
+--error ER_WRONG_TYPE_FOR_VAR
+SET global innodb_stats_method=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+SET global innodb_stats_method='some';
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_stats_method = @start_global_value;
+SELECT @@global.innodb_stats_method;

=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test	2011-01-04 17:46:01 +0000
+++ b/mysql-test/t/information_schema.test	2011-08-11 15:58:49 +0000
@@ -1543,8 +1543,6 @@ DROP TABLE t1, information_schema.tables
 LOCK TABLES t1 READ, information_schema.tables READ;
 DROP TABLE t1;
 
-# Wait till all disconnects are completed
---source include/wait_until_count_sessions.inc
 
 #
 # Bug #43834    Assertion in Natural_join_column::db_name() on an I_S query
@@ -1609,5 +1607,185 @@ drop view v1;
 
 
 --echo #
+--echo # Test for bug #12828477 - "MDL SUBSYSTEM CREATES BIG OVERHEAD FOR
+--echo #                           CERTAIN QUERIES TO INFORMATION_SCHEMA".
+--echo #
+--echo # Check that metadata locks which are acquired during the process
+--echo # of opening tables/.FRMs/.TRG files while filling I_S table are
+--echo # not kept to the end of statement. Keeping the locks has caused
+--echo # performance problems in cases when big number of tables (.FRMs
+--echo # or .TRG files) were scanned as cost of new lock acquisition has
+--echo # increased linearly.
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+use mysqltest;
+create table t0 (i int);
+create table t1 (j int);
+create table t2 (k int);
+
+--echo #
+--echo # Test that we don't keep locks in case when we to fill
+--echo # I_S table we perform full-blown table open.
+--echo #
+
+--echo # Acquire lock on 't2' so upcoming RENAME is
+--echo # blocked.
+lock tables t2 read;
+
+--echo #
+--echo # Switching to connection 'con12828477_1'. 
+--echo #
+connect (con12828477_1, localhost, root,,mysqltest);
+--echo # The below RENAME should wait on 't2' while
+--echo # keeping X lock on 't1'.
+--send rename table t1 to t3, t2 to t1, t3 to t2
+
+--echo #
+--echo # Switching to connection 'con12828477_2'. 
+--echo #
+connect (con12828477_2, localhost, root,,mysqltest);
+--echo # Wait while the above RENAME is blocked.
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = "Waiting for table metadata lock" and
+        info = "rename table t1 to t3, t2 to t1, t3 to t2";
+--source include/wait_condition.inc
+
+--echo # Issue query to I_S which will open 't0' and get
+--echo # blocked on 't1' because of RENAME.
+--send select table_name, auto_increment from information_schema.tables where table_schema='mysqltest'
+
+--echo #
+--echo # Switching to connection 'con12828477_3'. 
+--echo #
+connect (con12828477_3, localhost, root,,mysqltest);
+--echo # Wait while the above SELECT is blocked.
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = "Waiting for table metadata lock" and
+        info = "select table_name, auto_increment from information_schema.tables where table_schema='mysqltest'";
+--source include/wait_condition.inc
+
+--echo #
+--echo # Check that it holds no lock on 't0' so it can be renamed.
+rename table t0 to t4;
+
+--echo #
+--echo # Switching to connection 'default'.
+--echo #
+connection default;
+--echo #
+--echo # Unblock the first RENAME.
+unlock tables;
+
+--echo #
+--echo # Switching to connection 'con12828477_1'. 
+--echo #
+connection con12828477_1;
+--echo # Reap the first RENAME
+--reap
+
+--echo #
+--echo # Switching to connection 'con12828477_2'. 
+--echo #
+connection con12828477_2;
+--echo # Reap SELECT to I_S.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+--echo #
+connection default;
+
+--echo #
+--echo # Now test that we don't keep locks in case when we to fill
+--echo # I_S table we read .FRM or .TRG file only (this was the case
+--echo # for which problem existed).
+--echo #
+
+rename table t4 to t0;
+--echo # Acquire lock on 't2' so upcoming RENAME is
+--echo # blocked.
+lock tables t2 read;
+
+--echo #
+--echo # Switching to connection 'con12828477_1'. 
+--echo #
+connection con12828477_1;
+--echo # The below RENAME should wait on 't2' while
+--echo # keeping X lock on 't1'.
+--send rename table t1 to t3, t2 to t1, t3 to t2
+
+--echo #
+--echo # Switching to connection 'con12828477_2'. 
+--echo #
+connection con12828477_2;
+--echo # Wait while the above RENAME is blocked.
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = "Waiting for table metadata lock" and
+        info = "rename table t1 to t3, t2 to t1, t3 to t2";
+--source include/wait_condition.inc
+
+--echo # Issue query to I_S which will open 't0' and get
+--echo # blocked on 't1' because of RENAME.
+--send select event_object_table, trigger_name from information_schema.triggers where event_object_schema='mysqltest'
+
+--echo #
+--echo # Switching to connection 'con12828477_3'. 
+--echo #
+connection con12828477_3;
+--echo # Wait while the above SELECT is blocked.
+let $wait_condition=
+  select count(*) = 1 from information_schema.processlist
+  where state = "Waiting for table metadata lock" and
+        info = "select event_object_table, trigger_name from information_schema.triggers where event_object_schema='mysqltest'";
+--source include/wait_condition.inc
+
+--echo #
+--echo # Check that it holds no lock on 't0' so it can be renamed.
+rename table t0 to t4;
+
+--echo #
+--echo # Switching to connection 'default'.
+--echo #
+connection default;
+--echo #
+--echo # Unblock the first RENAME.
+unlock tables;
+
+--echo #
+--echo # Switching to connection 'con12828477_1'. 
+--echo #
+connection con12828477_1;
+--echo # Reap the first RENAME
+--reap
+
+--echo #
+--echo # Switching to connection 'con12828477_2'. 
+--echo #
+connection con12828477_2;
+--echo # Reap SELECT to I_S.
+--reap
+
+--echo #
+--echo # Switching to connection 'default'.
+--echo #
+connection default;
+disconnect con12828477_1;
+disconnect con12828477_2;
+disconnect con12828477_3;
+
+--echo #
+--echo # Clean-up.
+drop database mysqltest;
+
+
+--echo #
 --echo # End of 5.5 tests
 --echo #
+
+# Wait till all disconnects are completed
+--source include/wait_until_count_sessions.inc

=== added file 'mysql-test/t/mysql_plugin-master.opt'
--- a/mysql-test/t/mysql_plugin-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysql_plugin-master.opt	2011-07-19 14:17:58 +0000
@@ -0,0 +1 @@
+--plugin-dir=$DAEMONEXAMPLE_DIR

=== added file 'mysql-test/t/mysql_plugin.test'
--- a/mysql-test/t/mysql_plugin.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/mysql_plugin.test	2011-08-12 10:49:38 +0000
@@ -0,0 +1,318 @@
+#
+# Test mysql_plugin tool
+#
+# This test contains test cases for testing the mysql_plugin client with
+# the daemon_example plugin. Test cases include tests for:
+#
+#   - successful enable/disable
+#   - incorrect paths
+#   - missing paths/options
+#
+# Implementation Notes
+#
+# The mysql_plugin tool now accepts --mysqld the path to mysqld server. The
+# mysqld path is extracted from MYSQLD_BOOTSTRAP_CMD line. We also extract
+# the path of MYSQLD_BASEDIR (where mysql exists) and use it for the errmsg
+# file. The directories differ between Windows and Unix but the Perl script
+# included below will pick as per platform.
+#
+# The test is also designed to issue the --skip directive if the location of
+# the mysqld, my_print_defaults, or daemon_example.ini files cannot be found.
+#
+
+--source include/not_embedded.inc
+
+# Add the datadir, basedir, plugin_dir to the bootstrap command
+let $MYSQLD_DATADIR= `select @@datadir`;
+let $MYSQL_BASEDIR= `select @@basedir`;
+let $MYSQL_ERRMSG_BASEDIR=`select @@lc_messages_dir`;
+let $PLUGIN_DIR=`select @@plugin_dir`;
+
+--disable_abort_on_error
+
+# Perl script to extract the location of the basedir from environment
+# variables. This is needed to ensure the test will run on the PB machines
+# designed to test release as well as debug builds. It also checks for the
+# location of the my_print_defaults and daemon_example.ini files.
+
+perl;
+use File::Basename;
+  my ($mysqld)= split " ", $ENV{MYSQLD_BOOTSTRAP_CMD};
+  my $mysqld_basedir=dirname($mysqld);
+  my $my_print_defaults= $ENV{MYSQL_MY_PRINT_DEFAULTS};
+  my $my_print_defaults_basedir=dirname($my_print_defaults);
+  my $daemonexample_ini= "$ENV{DAEMONEXAMPLE_DIR}/daemon_example.ini";
+  my $plugindir_ini= "$ENV{PLUGIN_DIR}/daemon_example.ini";
+  my $notfound= "";
+  open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/mysqld.inc") or die;
+  print FILE "let \$MYSQLD= $mysqld;\n";
+  print FILE "let \$MYSQLD_BASEDIR= $mysqld_basedir;\n";
+  print FILE "let \$MYSQL_MY_PRINT_DEFAULTS_BASEDIR= $my_print_defaults_basedir;\n";
+  if ((!-e $daemonexample_ini) || (!-r $daemonexample_ini))
+  {
+    print FILE "let \$DAEMONEXAMPLE_DIR= $not_found;\n";
+  }
+  if ((!-e $plugindir_ini) || (!-r $plugindir_ini))
+  {
+    print FILE "let \$PLUGIN_DIR= $not_found;\n";
+  }
+  close FILE;
+EOF
+
+
+source $MYSQL_TMP_DIR/mysqld.inc;
+remove_file $MYSQL_TMP_DIR/mysqld.inc;
+
+# The mysql_plugin tool expects a directory structure like in the installed
+# mysql version, so errmsg.sys will be copied to "basedir/share", we create
+# and remove this structure. 
+
+--mkdir $MYSQLD_BASEDIR/share
+--mkdir $MYSQLD_BASEDIR/share/mysql
+--copy_file $MYSQL_ERRMSG_BASEDIR/english/errmsg.sys $MYSQLD_BASEDIR/share/errmsg.sys
+--copy_file $MYSQL_ERRMSG_BASEDIR/english/errmsg.sys $MYSQLD_BASEDIR/share/mysql/errmsg.sys
+
+# The mysql_plugin tool now accepts --my-print-defaults which points to the
+# executable my_print_defaults.exe we can get this path from the variable
+# $MYSQL_MY_PRINT_DEFAULTS.
+
+# Check for my_print_defaults location. Skip if not found.
+if ($MYSQL_MY_PRINT_DEFAULTS_BASEDIR == '')
+{
+  --skip Test requires known location of my_print_defaults executable.
+}
+
+# Check for mysqld location. Skip if not found.
+if ($MYSQLD == '')
+{
+  --skip Test requires known location of mysqld executable.
+}
+
+# Check for daemon_example.ini location. Skip if not found in either
+# the plugin_dir path or the daemon_example_dir path.
+if ($PLUGIN_DIR == '')
+{
+  if ($DAEMONEXAMPLE_DIR == '')
+  {
+    --skip Test requires known location of daemon_example.ini file.  
+  }
+  let $PLUGIN_DIR = $DAEMONEXAMPLE_DIR;
+}
+
+# Build client command for reuse.
+
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN --datadir=$MYSQLD_DATADIR --basedir=$MYSQLD_BASEDIR --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+
+--echo #
+--echo # Ensure the plugin isn't loaded.
+--echo #
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+
+--echo #
+--echo # Enable the plugin...
+--echo #
+let $expect_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+# MTR will remove this file later, but this might be too late.
+--error 0,1
+--remove_file $expect_file
+--write_file $expect_file
+wait
+EOF
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+
+#
+# Enable the plugin
+#
+--exec $MYSQL_PLUGIN_CMD ENABLE daemon_example
+
+#
+# Ensure enabling an enabled plugin doesn't fail
+--exec $MYSQL_PLUGIN_CMD ENABLE daemon_example
+
+#
+# Restart the server
+#
+--append_file $expect_file
+restart
+EOF
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--echo #
+--echo # Ensure the plugin is now loaded.
+--echo #
+--replace_regex /\.dll/.so/
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+
+--echo #
+--echo # Disable the plugin...
+--echo #
+# MTR will remove this file later, but this might be too late.
+--error 0,1
+--remove_file $expect_file
+--write_file $expect_file
+wait
+EOF
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+
+#
+# Disable the plugin
+#
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example
+
+#
+# Restart the server
+#
+--append_file $expect_file
+restart
+EOF
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--echo #
+--echo # Ensure the plugin isn't loaded.
+--echo #
+SELECT * FROM mysql.plugin WHERE name = 'daemon_example' ORDER BY name;
+
+#
+# Stop the server for error conditions
+#
+let $expect_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+# MTR will remove this file later, but this might be too late.
+--error 0,1
+--remove_file $expect_file
+--write_file $expect_file
+wait
+EOF
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+
+--echo #
+--echo # Attempt to load non-existant plugin
+--echo #
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE NOT_THERE_AT_ALL 2>&1
+
+--echo #
+--echo # Attempt to use non-existant plugin.ini file
+--echo #
+--error 1,2,7,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example --plugin-ini=/NOT/THERE/pi.ini 2>&1
+
+--echo # 
+--echo # Attempt to omit the plugin
+--echo #
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE 2>&1
+
+--echo # 
+--echo # Attempt to omit DISABLE|ENABLE
+--echo #
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD daemon_example 2>&1
+
+--echo # 
+--echo # Attempt to use bad paths - datadir
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=/data_not_there/ --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Attempt to use bad paths - basedir
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=/basedir_not_there/ --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Attempt to use bad paths - plugin_dir
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQL_BASEDIR --plugin-dir=/plugin_not_there/ --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Attempt to use bad paths - mysqld
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --mysqld=/mysqld_not_there/ --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Attempt to use bad paths - my_print_defaults
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=/my_print_defaults_not_there/;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+
+--echo # 
+--echo # Missing library
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --plugin-ini=$MYSQL_TEST_DIR/include/daemon_example_bad_soname.ini --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Bad format for config file
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --plugin-ini=$MYSQL_TEST_DIR/include/daemon_example_bad_format.ini --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Missing base_dir option
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQLD_DATADIR --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,139,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Missing data_dir option
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --basedir=$MYSQL_BASEDIR --plugin-dir=$PLUGIN_DIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,139,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo # 
+--echo # Missing plugin_dir option
+--echo #
+let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQL_DATADIR --basedir=$MYSQL_BASEDIR --mysqld=$MYSQLD_BASEDIR --my-print-defaults=$MYSQL_MY_PRINT_DEFAULTS_BASEDIR;
+--error 1,2,139,256
+--exec $MYSQL_PLUGIN_CMD DISABLE daemon_example 2>&1
+
+--echo #
+--echo # Show the help.
+--echo #
+replace_result $MYSQL_PLUGIN mysql_plugin;
+--replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/
+--exec $MYSQL_PLUGIN --help
+
+replace_result $MYSQL_PLUGIN mysql_plugin;
+--replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/
+--exec $MYSQL_PLUGIN --version
+
+#
+# Restart the server
+#
+--append_file $expect_file
+restart
+EOF
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+#
+# Cleanup
+# MTR will remove this file later, but this might be too late.
+--error 0,1
+--remove_file $expect_file
+
+# Cleanup the share folder in the binary path.
+--remove_file $MYSQLD_BASEDIR/share/errmsg.sys
+--rmdir $MYSQLD_BASEDIR/share/mysql
+--rmdir $MYSQLD_BASEDIR/share
+
+--enable_abort_on_error

=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test	2011-06-21 15:24:44 +0000
+++ b/mysql-test/t/sp.test	2011-08-02 07:54:35 +0000
@@ -8376,6 +8376,33 @@ SET @@GLOBAL.init_connect= @old_init_con
 DROP PROCEDURE p2;
 DROP PROCEDURE p5;
 
+--echo #
+--echo # Bug#11766594  59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, KEY(b));
+CREATE TABLE t2 (c INT, d INT, KEY(c));
+INSERT INTO t1 VALUES (1,1),(1,1),(1,2);
+INSERT INTO t2 VALUES (1,1),(1,2);
+
+DELIMITER $;
+
+CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
+BEGIN
+  DECLARE a int;
+  -- SQL statement inside
+  SELECT 1 INTO a;
+  RETURN a;
+END $
+
+DELIMITER ;$
+
+SELECT COUNT(DISTINCT d) FROM t1, t2  WHERE a = c AND b = f1();
+
+DROP FUNCTION f1;
+DROP TABLE t1, t2;
+
+
 --echo # ------------------------------------------------------------------
 --echo # -- End of 5.1 tests
 --echo # ------------------------------------------------------------------

=== modified file 'mysql-test/t/sp_trans.test'
--- a/mysql-test/t/sp_trans.test	2010-10-06 14:34:28 +0000
+++ b/mysql-test/t/sp_trans.test	2011-08-08 16:45:43 +0000
@@ -598,6 +598,39 @@ select distinct f1, bug13575(f1) from t3
 drop function bug13575|
 drop table t3|
 
+#
+# BUG#11758414: Default storage_engine not honored when set
+#               from within a stored procedure
+#
+SELECT @@GLOBAL.storage_engine INTO @old_engine|
+SET @@GLOBAL.storage_engine=InnoDB|
+SET @@SESSION.storage_engine=InnoDB|
+# show defaults at define-time
+SHOW GLOBAL VARIABLES LIKE 'storage_engine'|
+SHOW SESSION VARIABLES LIKE 'storage_engine'|
+CREATE PROCEDURE bug11758414()
+BEGIN
+ SET @@GLOBAL.storage_engine="MyISAM";
+ SET @@SESSION.storage_engine="MyISAM"; 
+ # show defaults at execution time / that setting them worked
+ SHOW GLOBAL VARIABLES LIKE 'storage_engine';
+ SHOW SESSION VARIABLES LIKE 'storage_engine';
+ CREATE TABLE t1 (id int);
+ CREATE TABLE t2 (id int) ENGINE=InnoDB;
+ # show we're heeding the default (at run-time, not parse-time!)
+ SHOW CREATE TABLE t1;
+ # show that we didn't break explicit override with ENGINE=...
+ SHOW CREATE TABLE t2;
+END;
+|
+CALL bug11758414|
+# show that changing defaults within SP stuck
+SHOW GLOBAL VARIABLES LIKE 'storage_engine'|
+SHOW SESSION VARIABLES LIKE 'storage_engine'|
+DROP PROCEDURE bug11758414|
+DROP TABLE t1, t2|
+SET @@GLOBAL.storage_engine=@old_engine|
+
 --echo #
 --echo # End of 5.1 tests
 --echo #

=== modified file 'mysys/my_handler_errors.h'
--- a/mysys/my_handler_errors.h	2011-06-30 15:46:53 +0000
+++ b/mysys/my_handler_errors.h	2011-08-17 01:07:59 +0000
@@ -81,7 +81,8 @@ static const char *handler_error_message
   "File to short; Expected more data in file",
   "Read page with wrong checksum",
   "Too many active concurrent transactions",
-  "Index column length exceeds limit"
+  "Index column length exceeds limit",
+  "Index corrupted"
 };
 
 extern void my_handler_error_register(void);

=== modified file 'plugin/daemon_example/CMakeLists.txt'
--- a/plugin/daemon_example/CMakeLists.txt	2010-08-12 15:19:57 +0000
+++ b/plugin/daemon_example/CMakeLists.txt	2011-07-19 14:17:58 +0000
@@ -15,3 +15,5 @@
 
 MYSQL_ADD_PLUGIN(daemon_example daemon_example.cc
   MODULE_ONLY MODULE_OUTPUT_NAME "libdaemon_example")
+
+INSTALL(FILES daemon_example.ini DESTINATION ${INSTALL_PLUGINDIR})

=== added file 'plugin/daemon_example/daemon_example.ini'
--- a/plugin/daemon_example/daemon_example.ini	1970-01-01 00:00:00 +0000
+++ b/plugin/daemon_example/daemon_example.ini	2011-07-19 14:24:14 +0000
@@ -0,0 +1,9 @@
+#
+# Plugin configuration file. Place the following on a separate line:
+#
+# library binary file name (without .so or .dll)
+# component_name
+# [component_name] - additional components in plugin
+#
+libdaemon_example
+daemon_example

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-07-03 23:48:19 +0000
+++ b/sql/handler.cc	2011-08-17 01:07:59 +0000
@@ -358,6 +358,7 @@ int ha_init_errors(void)
   SETMSG(HA_ERR_AUTOINC_ERANGE,         ER_DEFAULT(ER_WARN_DATA_OUT_OF_RANGE));
   SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER_DEFAULT(ER_TOO_MANY_CONCURRENT_TRXS));
   SETMSG(HA_ERR_INDEX_COL_TOO_LONG,	ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG));
+  SETMSG(HA_ERR_INDEX_CORRUPT,		ER_DEFAULT(ER_INDEX_CORRUPT));
 
   /* Register the error messages for use with my_error(). */
   return my_error_register(get_handler_errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -2865,6 +2866,9 @@ void handler::print_error(int error, myf
   case HA_ERR_INDEX_COL_TOO_LONG:
     textno= ER_INDEX_COLUMN_TOO_LONG;
     break;
+  case HA_ERR_INDEX_CORRUPT:
+    textno= ER_INDEX_CORRUPT;
+    break;
   default:
     {
       /* The error was "unknown" to this function.

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2011-06-10 07:20:15 +0000
+++ b/sql/share/errmsg-utf8.txt	2011-08-17 01:07:59 +0000
@@ -6415,3 +6415,5 @@ ER_ERROR_IN_TRIGGER_BODY
 ER_ERROR_IN_UNKNOWN_TRIGGER_BODY
   eng "Unknown trigger has an error in its body: '%-.256s'"
 
+ER_INDEX_CORRUPT
+  eng "Index %s is corrupted"

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-07-22 12:31:10 +0000
+++ b/sql/sql_base.cc	2011-08-02 07:54:35 +0000
@@ -7888,7 +7888,7 @@ bool setup_fields(THD *thd, Item **ref_p
     if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
 	sum_func_list)
       item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
-    thd->used_tables|= item->used_tables();
+    thd->lex->used_tables|= item->used_tables();
     thd->lex->current_select->cur_pos_in_select_list++;
   }
   thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
@@ -8235,7 +8235,7 @@ insert_fields(THD *thd, Name_resolution_
       views and natural joins this update is performed inside the loop below.
     */
     if (table)
-      thd->used_tables|= table->map;
+      thd->lex->used_tables|= table->map;
 
     /*
       Initialize a generic field iterator for the current table reference.
@@ -8320,7 +8320,7 @@ insert_fields(THD *thd, Name_resolution_
           field_table= nj_col->table_ref->table;
           if (field_table)
           {
-            thd->used_tables|= field_table->map;
+            thd->lex->used_tables|= field_table->map;
             field_table->covering_keys.intersect(field->part_of_key);
             field_table->merge_keys.merge(field->part_of_key);
             field_table->used_fields++;
@@ -8328,7 +8328,7 @@ insert_fields(THD *thd, Name_resolution_
         }
       }
       else
-        thd->used_tables|= item->used_tables();
+        thd->lex->used_tables|= item->used_tables();
       thd->lex->current_select->cur_pos_in_select_list++;
     }
     /*

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2011-07-20 06:50:47 +0000
+++ b/sql/sql_class.cc	2011-08-12 13:50:04 +0000
@@ -655,8 +655,8 @@ char *thd_security_context(THD *thd, cha
   const char *proc_info= thd->proc_info;
 
   len= my_snprintf(header, sizeof(header),
-                   "MySQL thread id %lu, query id %lu",
-                   thd->thread_id, (ulong) thd->query_id);
+                   "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu",
+                   thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id);
   str.length(0);
   str.append(header, len);
 
@@ -795,7 +795,6 @@ THD::THD()
   is_slave_error= thread_specific_used= FALSE;
   my_hash_clear(&handler_tables_hash);
   tmp_table=0;
-  used_tables=0;
   cuted_fields= 0L;
   sent_row_count= 0L;
   limit_found_rows= 0;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-07-07 11:22:43 +0000
+++ b/sql/sql_class.h	2011-08-02 07:54:35 +0000
@@ -1960,13 +1960,6 @@ public:
   */
   ha_rows    examined_row_count;
 
-  /*
-    The set of those tables whose fields are referenced in all subqueries
-    of the query.
-    TODO: possibly this it is incorrect to have used tables in THD because
-    with more than one subquery, it is not clear what does the field mean.
-  */
-  table_map  used_tables;
   USER_CONN *user_connect;
   CHARSET_INFO *db_charset;
   Warning_info *warning_info;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2011-07-03 23:48:19 +0000
+++ b/sql/sql_insert.cc	2011-08-03 13:53:44 +0000
@@ -717,7 +717,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   lock_type= table_list->lock_type;
 
   thd_proc_info(thd, "init");
-  thd->used_tables=0;
+  thd->lex->used_tables=0;
   values= its++;
   value_count= values->elements;
 
@@ -872,7 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     }
     else
     {
-      if (thd->used_tables)			// Column used in values()
+      if (thd->lex->used_tables)		      // Column used in values()
 	restore_record(table,s->default_values);	// Get empty record
       else
       {
@@ -1610,9 +1610,6 @@ int write_record(THD *thd, TABLE *table,
           goto before_trg_err;
 
         table->file->restore_auto_increment(prev_insert_id);
-        if (table->next_number_field)
-          table->file->adjust_next_insert_id_after_explicit_value(
-            table->next_number_field->val_int());
         info->touched++;
         if (!records_are_comparable(table) || compare_records(table))
         {
@@ -1649,8 +1646,6 @@ int write_record(THD *thd, TABLE *table,
         if (table->next_number_field)
           table->file->adjust_next_insert_id_after_explicit_value(
             table->next_number_field->val_int());
-        info->touched++;
-
         goto ok_or_after_trg_err;
       }
       else /* DUP_REPLACE */

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2011-07-07 09:42:14 +0000
+++ b/sql/sql_lex.cc	2011-08-02 07:54:35 +0000
@@ -434,6 +434,7 @@ void lex_start(THD *thd)
   lex->server_options.port= -1;
 
   lex->is_lex_started= TRUE;
+  lex->used_tables= 0;
   DBUG_VOID_RETURN;
 }
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-07-18 17:18:03 +0000
+++ b/sql/sql_lex.h	2011-08-02 07:54:35 +0000
@@ -2396,6 +2396,16 @@ struct LEX: public Query_tables_list
   bool escape_used;
   bool is_lex_started; /* If lex_start() did run. For debugging. */
 
+  /*
+    The set of those tables whose fields are referenced in all subqueries
+    of the query.
+    TODO: possibly this it is incorrect to have used tables in LEX because
+    with subquery, it is not clear what does the field mean. To fix this
+    we should aggregate used tables information for selected expressions
+    into the select_lex.
+  */
+  table_map  used_tables;
+
   LEX();
 
   virtual ~LEX()

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-07-03 23:48:19 +0000
+++ b/sql/sql_parse.cc	2011-08-08 16:45:43 +0000
@@ -2348,6 +2348,12 @@ case SQLCOM_PREPARE:
       goto end_with_restore_list;
 #endif
     /*
+      If no engine type was given, work out the default now
+      rather than at parse-time.
+    */
+    if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
+      create_info.db_type= ha_default_handlerton(thd);
+    /*
       If we are using SET CHARSET without DEFAULT, add an implicit
       DEFAULT to not confuse old users. (This may change).
     */

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2011-07-03 23:48:19 +0000
+++ b/sql/sql_prepare.cc	2011-08-02 07:54:35 +0000
@@ -1474,7 +1474,7 @@ static int mysql_test_select(Prepared_st
   if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
     goto error;
 
-  thd->used_tables= 0;                        // Updated by setup_fields
+  thd->lex->used_tables= 0;                        // Updated by setup_fields
 
   /*
     JOIN::prepare calls
@@ -1646,7 +1646,7 @@ static bool select_like_stmt_test(Prepar
   if (specific_prepare && (*specific_prepare)(thd))
     DBUG_RETURN(TRUE);
 
-  thd->used_tables= 0;                        // Updated by setup_fields
+  thd->lex->used_tables= 0;                        // Updated by setup_fields
 
   /* Calls JOIN::prepare */
   DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-07-07 09:42:14 +0000
+++ b/sql/sql_select.cc	2011-08-02 07:54:35 +0000
@@ -435,7 +435,7 @@ fix_inner_refs(THD *thd, List<Item> &all
 
     if (!ref->fixed && ref->fix_fields(thd, 0))
       return TRUE;
-    thd->used_tables|= item->used_tables();
+    thd->lex->used_tables|= item->used_tables();
   }
   return false;
 }
@@ -1675,7 +1675,7 @@ JOIN::optimize()
 
     if (exec_tmp_table1->distinct)
     {
-      table_map used_tables= thd->used_tables;
+      table_map used_tables= thd->lex->used_tables;
       JOIN_TAB *last_join_tab= join_tab+tables-1;
       do
       {
@@ -2552,7 +2552,7 @@ mysql_select(THD *thd, Item ***rref_poin
     if (!(join= new JOIN(thd, fields, select_options, result)))
 	DBUG_RETURN(TRUE);
     thd_proc_info(thd, "init");
-    thd->used_tables=0;                         // Updated by setup_fields
+    thd->lex->used_tables=0;                         // Updated by setup_fields
     err= join->prepare(rref_pointer_array, tables, wild_num,
                        conds, og_num, order, group, having, proc_param,
                        select_lex, unit);
@@ -17032,7 +17032,7 @@ static void select_describe(JOIN *join, 
 	  need_order=0;
 	  extra.append(STRING_WITH_LEN("; Using filesort"));
 	}
-	if (distinct & test_all_bits(used_tables,thd->used_tables))
+	if (distinct & test_all_bits(used_tables, thd->lex->used_tables))
 	  extra.append(STRING_WITH_LEN("; Distinct"));
 
         for (uint part= 0; part < tab->ref.key_parts; part++)

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2011-07-03 23:48:19 +0000
+++ b/sql/sql_show.cc	2011-08-11 15:58:49 +0000
@@ -3157,6 +3157,10 @@ end:
   */
   thd->temporary_tables= NULL;
   close_thread_tables(thd);
+  /*
+    Release metadata lock we might have acquired.
+    See comment in fill_schema_table_from_frm() for details.
+  */
   thd->mdl_context.rollback_to_savepoint(open_tables_state_backup->mdl_system_tables_svp);
 
   thd->lex= old_lex;
@@ -3339,6 +3343,9 @@ try_acquire_high_prio_shared_mdl_lock(TH
   @param[in]      db_name                  database name
   @param[in]      table_name               table name
   @param[in]      schema_table_idx         I_S table index
+  @param[in]      open_tables_state_backup Open_tables_state object which is used
+                                           to save/restore original state of metadata
+                                           locks.
   @param[in]      can_deadlock             Indicates that deadlocks are possible
                                            due to metadata locks, so to avoid
                                            them we should not wait in case if
@@ -3356,6 +3363,7 @@ static int fill_schema_table_from_frm(TH
                                       LEX_STRING *db_name,
                                       LEX_STRING *table_name,
                                       enum enum_schema_tables schema_table_idx,
+                                      Open_tables_backup *open_tables_state_backup,
                                       bool can_deadlock)
 {
   TABLE *table= tables->table;
@@ -3501,13 +3509,27 @@ end_share:
 
 end_unlock:
   mysql_mutex_unlock(&LOCK_open);
-  /*
-    Don't release the MDL lock, it can be part of a transaction.
-    If it is not, it will be released by the call to
-    MDL_context::rollback_to_savepoint() in the caller.
-  */
 
 end:
+  /*
+    Release metadata lock we might have acquired.
+
+    Without this step metadata locks acquired for each table processed
+    will be accumulated. In situation when a lot of tables are processed
+    by I_S query this will result in transaction with too many metadata
+    locks. As result performance of acquisition of new lock will suffer.
+
+    Of course, the fact that we don't hold metadata lock on tables which
+    were processed till the end of I_S query makes execution less isolated
+    from concurrent DDL. Consequently one might get 'dirty' results from
+    such a query. But we have never promised serializability of I_S queries
+    anyway.
+
+    We don't have any tables open since we took backup, so rolling back to
+    savepoint is safe.
+  */
+  DBUG_ASSERT(thd->open_tables == NULL);
+  thd->mdl_context.rollback_to_savepoint(open_tables_state_backup->mdl_system_tables_svp);
   thd->clear_error();
   return res;
 }
@@ -3758,6 +3780,7 @@ int get_all_tables(THD *thd, TABLE_LIST 
               int res= fill_schema_table_from_frm(thd, tables, schema_table,
                                                   db_name, table_name,
                                                   schema_table_idx,
+                                                  &open_tables_state_backup,
                                                   can_deadlock);
 
               thd->pop_internal_handler();

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-07-24 11:26:58 +0000
+++ b/sql/sql_yacc.yy	2011-08-11 08:34:16 +0000
@@ -2038,7 +2038,6 @@ create:
             lex->change=NullS;
             bzero((char*) &lex->create_info,sizeof(lex->create_info));
             lex->create_info.options=$2 | $4;
-            lex->create_info.db_type= ha_default_handlerton(thd);
             lex->create_info.default_table_charset= NULL;
             lex->name.str= 0;
             lex->name.length= 0;
@@ -2048,7 +2047,8 @@ create:
           {
             LEX *lex= YYTHD->lex;
             lex->current_select= &lex->select_lex; 
-            if (!lex->create_info.db_type)
+            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
+                !lex->create_info.db_type)
             {
               lex->create_info.db_type= ha_default_handlerton(YYTHD);
               push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -5036,8 +5036,7 @@ create_table_option:
           ENGINE_SYM opt_equal storage_engines
           {
             Lex->create_info.db_type= $3;
-            if ($3)
-              Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
+            Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
           }
         | MAX_ROWS opt_equal ulonglong_num
           {
@@ -6748,6 +6747,11 @@ alter_list_item:
           {
             LEX *lex=Lex;
             lex->alter_info.flags|= ALTER_OPTIONS;
+            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
+                !lex->create_info.db_type)
+            {
+              lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
+            }
           }
         | FORCE_SYM
           {

=== modified file 'storage/innobase/btr/btr0btr.c'
--- a/storage/innobase/btr/btr0btr.c	2011-06-16 13:14:16 +0000
+++ b/storage/innobase/btr/btr0btr.c	2011-08-15 09:18:34 +0000
@@ -690,7 +690,8 @@ btr_root_block_get(
 	zip_size = dict_table_zip_size(index->table);
 	root_page_no = dict_index_get_page(index);
 
-	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
+	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
+			      index, mtr);
 	ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
 	     == dict_table_is_comp(index->table));
 #ifdef UNIV_BTR_DEBUG
@@ -891,7 +892,7 @@ btr_page_alloc_for_ibuf(
 				 dict_table_zip_size(index->table),
 				 node_addr.page, RW_X_LATCH, mtr);
 	new_page = buf_block_get_frame(new_block);
-	buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW);
+	buf_block_dbg_add_level(new_block, SYNC_IBUF_TREE_NODE_NEW);
 
 	flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
 		    new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
@@ -1139,7 +1140,7 @@ btr_node_ptr_get_child(
 	page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 
 	return(btr_block_get(space, dict_table_zip_size(index->table),
-			     page_no, RW_X_LATCH, mtr));
+			     page_no, RW_X_LATCH, index, mtr));
 }
 
 /************************************************************//**
@@ -1312,7 +1313,8 @@ btr_create(
 			space, 0,
 			IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr);
 
-		buf_block_dbg_add_level(ibuf_hdr_block, SYNC_TREE_NODE_NEW);
+		buf_block_dbg_add_level(
+			ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW);
 
 		ut_ad(buf_block_get_page_no(ibuf_hdr_block)
 		      == IBUF_HEADER_PAGE_NO);
@@ -1350,10 +1352,9 @@ btr_create(
 	page_no = buf_block_get_page_no(block);
 	frame = buf_block_get_frame(block);
 
-	buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
-
 	if (type & DICT_IBUF) {
 		/* It is an insert buffer tree: initialize the free list */
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
 
 		ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO);
 
@@ -1361,6 +1362,8 @@ btr_create(
 	} else {
 		/* It is a non-ibuf tree: create a file segment for leaf
 		pages */
+		buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
+
 		if (!fseg_create(space, page_no,
 				 PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) {
 			/* Not enough space for new segment, free root
@@ -1432,7 +1435,8 @@ btr_free_but_not_root(
 leaf_loop:
 	mtr_start(&mtr);
 
-	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
+	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
+			    NULL, &mtr);
 #ifdef UNIV_BTR_DEBUG
 	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
 				    + root, space));
@@ -1454,7 +1458,8 @@ leaf_loop:
 top_loop:
 	mtr_start(&mtr);
 
-	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
+	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH,
+			    NULL, &mtr);
 #ifdef UNIV_BTR_DEBUG
 	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
 				    + root, space));
@@ -1480,13 +1485,13 @@ btr_free_root(
 	ulint	zip_size,	/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
 	ulint	root_page_no,	/*!< in: root page number */
-	mtr_t*	mtr)		/*!< in: a mini-transaction which has already
-				been started */
+	mtr_t*	mtr)		/*!< in/out: mini-transaction */
 {
 	buf_block_t*	block;
 	fseg_header_t*	header;
 
-	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
+	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH,
+			      NULL, mtr);
 
 	btr_search_drop_page_hash_index(block);
 
@@ -2365,9 +2370,8 @@ btr_attach_half_pages(
 	/* Update page links of the level */
 
 	if (prev_page_no != FIL_NULL) {
-		buf_block_t*	prev_block = btr_block_get(space, zip_size,
-							   prev_page_no,
-							   RW_X_LATCH, mtr);
+		buf_block_t*	prev_block = btr_block_get(
+			space, zip_size, prev_page_no, RW_X_LATCH, index, mtr);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(prev_block->frame) == page_is_comp(page));
 		ut_a(btr_page_get_next(prev_block->frame, mtr)
@@ -2380,9 +2384,8 @@ btr_attach_half_pages(
 	}
 
 	if (next_page_no != FIL_NULL) {
-		buf_block_t*	next_block = btr_block_get(space, zip_size,
-							   next_page_no,
-							   RW_X_LATCH, mtr);
+		buf_block_t*	next_block = btr_block_get(
+			space, zip_size, next_page_no, RW_X_LATCH, index, mtr);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(next_block->frame) == page_is_comp(page));
 		ut_a(btr_page_get_prev(next_block->frame, mtr)
@@ -2804,17 +2807,42 @@ func_exit:
 	return(rec);
 }
 
+#ifdef UNIV_SYNC_DEBUG
+/*************************************************************//**
+Removes a page from the level list of pages.
+@param space	in: space where removed
+@param zip_size	in: compressed page size in bytes, or 0 for uncompressed
+@param page	in/out: page to remove
+@param index	in: index tree
+@param mtr	in/out: mini-transaction */
+# define btr_level_list_remove(space,zip_size,page,index,mtr)		\
+	btr_level_list_remove_func(space,zip_size,page,index,mtr)
+#else /* UNIV_SYNC_DEBUG */
+/*************************************************************//**
+Removes a page from the level list of pages.
+@param space	in: space where removed
+@param zip_size	in: compressed page size in bytes, or 0 for uncompressed
+@param page	in/out: page to remove
+@param index	in: index tree
+@param mtr	in/out: mini-transaction */
+# define btr_level_list_remove(space,zip_size,page,index,mtr)		\
+	btr_level_list_remove_func(space,zip_size,page,mtr)
+#endif /* UNIV_SYNC_DEBUG */
+
 /*************************************************************//**
 Removes a page from the level list of pages. */
-static
+static __attribute__((nonnull))
 void
-btr_level_list_remove(
-/*==================*/
-	ulint		space,	/*!< in: space where removed */
-	ulint		zip_size,/*!< in: compressed page size in bytes
-				or 0 for uncompressed pages */
-	page_t*		page,	/*!< in: page to remove */
-	mtr_t*		mtr)	/*!< in: mtr */
+btr_level_list_remove_func(
+/*=======================*/
+	ulint			space,	/*!< in: space where removed */
+	ulint			zip_size,/*!< in: compressed page size in bytes
+					or 0 for uncompressed pages */
+	page_t*			page,	/*!< in/out: page to remove */
+#ifdef UNIV_SYNC_DEBUG
+	const dict_index_t*	index,	/*!< in: index tree */
+#endif /* UNIV_SYNC_DEBUG */
+	mtr_t*			mtr)	/*!< in/out: mini-transaction */
 {
 	ulint	prev_page_no;
 	ulint	next_page_no;
@@ -2832,7 +2860,7 @@ btr_level_list_remove(
 	if (prev_page_no != FIL_NULL) {
 		buf_block_t*	prev_block
 			= btr_block_get(space, zip_size, prev_page_no,
-					RW_X_LATCH, mtr);
+					RW_X_LATCH, index, mtr);
 		page_t*		prev_page
 			= buf_block_get_frame(prev_block);
 #ifdef UNIV_BTR_DEBUG
@@ -2849,7 +2877,7 @@ btr_level_list_remove(
 	if (next_page_no != FIL_NULL) {
 		buf_block_t*	next_block
 			= btr_block_get(space, zip_size, next_page_no,
-					RW_X_LATCH, mtr);
+					RW_X_LATCH, index, mtr);
 		page_t*		next_page
 			= buf_block_get_frame(next_block);
 #ifdef UNIV_BTR_DEBUG
@@ -3175,7 +3203,7 @@ btr_compress(
 	if (is_left) {
 
 		merge_block = btr_block_get(space, zip_size, left_page_no,
-					    RW_X_LATCH, mtr);
+					    RW_X_LATCH, index, mtr);
 		merge_page = buf_block_get_frame(merge_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(btr_page_get_next(merge_page, mtr)
@@ -3184,7 +3212,7 @@ btr_compress(
 	} else if (right_page_no != FIL_NULL) {
 
 		merge_block = btr_block_get(space, zip_size, right_page_no,
-					    RW_X_LATCH, mtr);
+					    RW_X_LATCH, index, mtr);
 		merge_page = buf_block_get_frame(merge_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(btr_page_get_prev(merge_page, mtr)
@@ -3273,7 +3301,7 @@ err_exit:
 		btr_search_drop_page_hash_index(block);
 
 		/* Remove the page from the level list */
-		btr_level_list_remove(space, zip_size, page, mtr);
+		btr_level_list_remove(space, zip_size, page, index, mtr);
 
 		btr_node_ptr_delete(index, block, mtr);
 		lock_update_merge_left(merge_block, orig_pred, block);
@@ -3330,7 +3358,7 @@ err_exit:
 #endif /* UNIV_BTR_DEBUG */
 
 		/* Remove the page from the level list */
-		btr_level_list_remove(space, zip_size, page, mtr);
+		btr_level_list_remove(space, zip_size, page, index, mtr);
 
 		/* Replace the address of the old child node (= page) with the
 		address of the merge page to the right */
@@ -3522,7 +3550,7 @@ btr_discard_page(
 
 	if (left_page_no != FIL_NULL) {
 		merge_block = btr_block_get(space, zip_size, left_page_no,
-					    RW_X_LATCH, mtr);
+					    RW_X_LATCH, index, mtr);
 		merge_page = buf_block_get_frame(merge_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(btr_page_get_next(merge_page, mtr)
@@ -3530,7 +3558,7 @@ btr_discard_page(
 #endif /* UNIV_BTR_DEBUG */
 	} else if (right_page_no != FIL_NULL) {
 		merge_block = btr_block_get(space, zip_size, right_page_no,
-					    RW_X_LATCH, mtr);
+					    RW_X_LATCH, index, mtr);
 		merge_page = buf_block_get_frame(merge_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(btr_page_get_prev(merge_page, mtr)
@@ -3565,7 +3593,7 @@ btr_discard_page(
 	btr_node_ptr_delete(index, block, mtr);
 
 	/* Remove the page from the level list */
-	btr_level_list_remove(space, zip_size, page, mtr);
+	btr_level_list_remove(space, zip_size, page, index, mtr);
 #ifdef UNIV_ZIP_DEBUG
 	{
 		page_zip_des_t*	merge_page_zip
@@ -4083,7 +4111,7 @@ loop:
 	if (right_page_no != FIL_NULL) {
 		const rec_t*	right_rec;
 		right_block = btr_block_get(space, zip_size, right_page_no,
-					    RW_X_LATCH, &mtr);
+					    RW_X_LATCH, index, &mtr);
 		right_page = buf_block_get_frame(right_block);
 		if (UNIV_UNLIKELY(btr_page_get_prev(right_page, &mtr)
 				  != page_get_page_no(page))) {
@@ -4309,7 +4337,7 @@ node_ptr_fails:
 		mtr_start(&mtr);
 
 		block = btr_block_get(space, zip_size, right_page_no,
-				      RW_X_LATCH, &mtr);
+				      RW_X_LATCH, index, &mtr);
 		page = buf_block_get_frame(block);
 
 		goto loop;

=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c	2011-07-07 11:22:43 +0000
+++ b/storage/innobase/btr/btr0cur.c	2011-08-15 09:18:34 +0000
@@ -249,7 +249,8 @@ btr_cur_latch_leaves(
 	case BTR_SEARCH_LEAF:
 	case BTR_MODIFY_LEAF:
 		mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
-		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
+		get_block = btr_block_get(
+			space, zip_size, page_no, mode, cursor->index, mtr);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -260,9 +261,9 @@ btr_cur_latch_leaves(
 		left_page_no = btr_page_get_prev(page, mtr);
 
 		if (left_page_no != FIL_NULL) {
-			get_block = btr_block_get(space, zip_size,
-						  left_page_no,
-						  RW_X_LATCH, mtr);
+			get_block = btr_block_get(
+				space, zip_size, left_page_no,
+				RW_X_LATCH, cursor->index, mtr);
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
 			     == page_is_comp(page));
@@ -272,8 +273,9 @@ btr_cur_latch_leaves(
 			get_block->check_index_page_at_flush = TRUE;
 		}
 
-		get_block = btr_block_get(space, zip_size, page_no,
-					  RW_X_LATCH, mtr);
+		get_block = btr_block_get(
+			space, zip_size, page_no,
+			RW_X_LATCH, cursor->index, mtr);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -282,9 +284,9 @@ btr_cur_latch_leaves(
 		right_page_no = btr_page_get_next(page, mtr);
 
 		if (right_page_no != FIL_NULL) {
-			get_block = btr_block_get(space, zip_size,
-						  right_page_no,
-						  RW_X_LATCH, mtr);
+			get_block = btr_block_get(
+				space, zip_size, right_page_no,
+				RW_X_LATCH, cursor->index, mtr);
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
 			     == page_is_comp(page));
@@ -303,8 +305,9 @@ btr_cur_latch_leaves(
 		left_page_no = btr_page_get_prev(page, mtr);
 
 		if (left_page_no != FIL_NULL) {
-			get_block = btr_block_get(space, zip_size,
-						  left_page_no, mode, mtr);
+			get_block = btr_block_get(
+				space, zip_size,
+				left_page_no, mode, cursor->index, mtr);
 			cursor->left_block = get_block;
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
@@ -315,7 +318,8 @@ btr_cur_latch_leaves(
 			get_block->check_index_page_at_flush = TRUE;
 		}
 
-		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
+		get_block = btr_block_get(
+			space, zip_size, page_no, mode, cursor->index, mtr);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -669,7 +673,9 @@ retry_page_get:
 		ut_a(!page_zip || page_zip_validate(page_zip, page));
 #endif /* UNIV_ZIP_DEBUG */
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		buf_block_dbg_add_level(
+			block, dict_index_is_ibuf(index)
+			? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
 	}
 
 	ut_ad(index->id == btr_page_get_index_id(page));
@@ -767,7 +773,7 @@ retry_page_get:
 	if (level != 0) {
 		/* x-latch the page */
 		page = btr_page_get(
-			space, zip_size, page_no, RW_X_LATCH, mtr);
+			space, zip_size, page_no, RW_X_LATCH, index, mtr);
 
 		ut_a((ibool)!!page_is_comp(page)
 		     == dict_table_is_comp(index->table));

=== modified file 'storage/innobase/btr/btr0pcur.c'
--- a/storage/innobase/btr/btr0pcur.c	2010-10-01 13:36:35 +0000
+++ b/storage/innobase/btr/btr0pcur.c	2011-08-15 09:18:34 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -266,8 +266,10 @@ btr_pcur_restore_position_func(
 					file, line, mtr))) {
 			cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 
-			buf_block_dbg_add_level(btr_pcur_get_block(cursor),
-						SYNC_TREE_NODE);
+			buf_block_dbg_add_level(
+				btr_pcur_get_block(cursor),
+				dict_index_is_ibuf(index)
+				? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
 
 			if (cursor->rel_pos == BTR_PCUR_ON) {
 #ifdef UNIV_DEBUG
@@ -417,7 +419,8 @@ btr_pcur_move_to_next_page(
 	ut_ad(next_page_no != FIL_NULL);
 
 	next_block = btr_block_get(space, zip_size, next_page_no,
-				   cursor->latch_mode, mtr);
+				   cursor->latch_mode,
+				   btr_pcur_get_btr_cur(cursor)->index, mtr);
 	next_page = buf_block_get_frame(next_block);
 #ifdef UNIV_BTR_DEBUG
 	ut_a(page_is_comp(next_page) == page_is_comp(page));

=== modified file 'storage/innobase/btr/btr0sea.c'
--- a/storage/innobase/btr/btr0sea.c	2011-02-28 13:39:07 +0000
+++ b/storage/innobase/btr/btr0sea.c	2011-08-15 09:18:34 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 Copyright (c) 2008, Google Inc.
 
 Portions of this file contain modifications contributed and copyrighted by
@@ -845,6 +845,7 @@ btr_search_guess_on_hash(
 	btr_pcur_t	pcur;
 #endif
 	ut_ad(index && info && tuple && cursor && mtr);
+	ut_ad(!dict_index_is_ibuf(index));
 	ut_ad((latch_mode == BTR_SEARCH_LEAF)
 	      || (latch_mode == BTR_MODIFY_LEAF));
 

=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	2011-07-19 14:54:59 +0000
+++ b/storage/innobase/buf/buf0buf.c	2011-08-17 03:51:40 +0000
@@ -3474,6 +3474,53 @@ buf_page_create(
 }
 
 /********************************************************************//**
+Mark a table with the specified space pointed by bpage->space corrupted.
+Also remove the bpage from LRU list.
+@return TRUE if successful */
+static
+ibool
+buf_mark_space_corrupt(
+/*===================*/
+	buf_page_t*	bpage)	/*!< in: pointer to the block in question */
+{
+	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
+	const ibool	uncompressed = (buf_page_get_state(bpage)
+					== BUF_BLOCK_FILE_PAGE);
+	ulint		space = bpage->space;
+	ibool		ret = TRUE;
+
+	/* First unfix and release lock on the bpage */
+	buf_pool_mutex_enter(buf_pool);
+	mutex_enter(buf_page_get_mutex(bpage));
+	ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
+	ut_ad(bpage->buf_fix_count == 0);
+
+	/* Set BUF_IO_NONE before we remove the block from LRU list */
+	buf_page_set_io_fix(bpage, BUF_IO_NONE);
+
+	if (uncompressed) {
+		rw_lock_x_unlock_gen(
+			&((buf_block_t*) bpage)->lock,
+			BUF_IO_READ);
+	}
+
+	/* Find the table with specified space id, and mark it corrupted */
+	if (dict_set_corrupted_by_space(space)) {
+		buf_LRU_free_one_page(bpage);
+	} else {
+		ret = FALSE;
+	}
+
+	ut_ad(buf_pool->n_pend_reads > 0);
+	buf_pool->n_pend_reads--;
+
+	mutex_exit(buf_page_get_mutex(bpage));
+	buf_pool_mutex_exit(buf_pool);
+
+	return(ret);
+}
+
+/********************************************************************//**
 Completes an asynchronous read or write request of a file page to or from
 the buffer pool. */
 UNIV_INTERN
@@ -3598,10 +3645,19 @@ corrupt:
 			      "InnoDB: about forcing recovery.\n", stderr);
 
 			if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
-				fputs("InnoDB: Ending processing because of"
-				      " a corrupt database page.\n",
-				      stderr);
-				exit(1);
+				/* If page space id is larger than TRX_SYS_SPACE
+				(0), we will attempt to mark the corresponding
+				table as corrupted instead of crashing server */
+				if (bpage->space > TRX_SYS_SPACE
+				    && buf_mark_space_corrupt(bpage)) {
+					return;
+				} else {
+					fputs("InnoDB: Ending processing"
+					      " because of"
+					      " a corrupt database page.\n",
+					      stderr);
+					ut_error;
+				}
 			}
 		}
 

=== modified file 'storage/innobase/buf/buf0lru.c'
--- a/storage/innobase/buf/buf0lru.c	2011-06-23 12:57:25 +0000
+++ b/storage/innobase/buf/buf0lru.c	2011-08-17 01:07:59 +0000
@@ -1885,6 +1885,22 @@ buf_LRU_block_free_hashed_page(
 	buf_LRU_block_free_non_file_page(block);
 }
 
+/******************************************************************//**
+Remove one page from LRU list and put it to free list */
+UNIV_INTERN
+void
+buf_LRU_free_one_page(
+/*==================*/
+	buf_page_t*	bpage)	/*!< in/out: block, must contain a file page and
+				be in a state where it can be freed; there
+				may or may not be a hash index to the page */
+{
+	if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
+	    != BUF_BLOCK_ZIP_FREE) {
+		buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
+	}
+}
+
 /**********************************************************************//**
 Updates buf_pool->LRU_old_ratio for one buffer pool instance.
 @return	updated old_pct */

=== modified file 'storage/innobase/dict/dict0crea.c'
--- a/storage/innobase/dict/dict0crea.c	2011-05-09 08:12:26 +0000
+++ b/storage/innobase/dict/dict0crea.c	2011-08-15 09:18:34 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -827,7 +827,7 @@ dict_truncate_index_tree(
 	appropriate field in the SYS_INDEXES record: this mini-transaction
 	marks the B-tree totally truncated */
 
-	btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
+	btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, NULL, mtr);
 
 	btr_free_root(space, zip_size, root_page_no, mtr);
 create:

=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/dict/dict0dict.c	2011-08-17 01:07:59 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -54,6 +54,7 @@ UNIV_INTERN dict_index_t*	dict_ind_compa
 #include "row0merge.h"
 #include "m_ctype.h" /* my_isspace() */
 #include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/
+#include "row0upd.h"
 
 #include <ctype.h>
 
@@ -611,8 +612,7 @@ dict_table_get_on_id(
 {
 	dict_table_t*	table;
 
-	if (table_id <= DICT_FIELDS_ID
-	    || trx->dict_operation_lock_mode == RW_X_LATCH) {
+	if (trx->dict_operation_lock_mode == RW_X_LATCH) {
 
 		/* Note: An X latch implies that the transaction
 		already owns the dictionary mutex. */
@@ -1714,7 +1714,8 @@ undo_size_ok:
 
 	new_index->page = page_no;
 	rw_lock_create(index_tree_rw_lock_key, &new_index->lock,
-		       SYNC_INDEX_TREE);
+		       dict_index_is_ibuf(index)
+		       ? SYNC_IBUF_INDEX_TREE : SYNC_INDEX_TREE);
 
 	if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
 
@@ -5045,4 +5046,179 @@ dict_close(void)
 		rw_lock_free(&dict_table_stats_latches[i]);
 	}
 }
+
+/**********************************************************************//**
+Find a table in dict_sys->table_LRU list with specified space id
+@return table if found, NULL if not */
+static
+dict_table_t*
+dict_find_table_by_space(
+/*=====================*/
+	ulint	space_id)		/*!< in: space ID */
+{
+	dict_table_t*   table;
+	ulint		num_item;
+	ulint		count = 0;
+
+	ut_ad(space_id > 0);
+
+	table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
+	num_item =  UT_LIST_GET_LEN(dict_sys->table_LRU);
+
+	/* This function intentionally does not acquire mutex as it is used
+	by error handling code in deep call stack as last means to avoid
+	killing the server, so it worth to risk some consequencies for
+	the action. */
+	while (table && count < num_item) {
+		if (table->space == space_id) {
+			return(table);
+		}
+
+		table = UT_LIST_GET_NEXT(table_LRU, table);
+		count++;
+	}
+
+	return(NULL);
+}
+
+/**********************************************************************//**
+Flags a table with specified space_id corrupted in the data dictionary
+cache
+@return TRUE if successful */
+UNIV_INTERN
+ibool
+dict_set_corrupted_by_space(
+/*========================*/
+	ulint	space_id)		/*!< in: space ID */
+{
+	dict_table_t*   table;
+
+	table = dict_find_table_by_space(space_id);
+
+	if (!table) {
+		return(FALSE);
+	}
+
+	/* mark the table->corrupted bit only, since the caller
+	could be too deep in the stack for SYS_INDEXES update */
+	table->corrupted = TRUE;
+
+	return(TRUE);
+}
+
+/**********************************************************************//**
+Flags an index corrupted both in the data dictionary cache
+and in the SYS_INDEXES */
+UNIV_INTERN
+void
+dict_set_corrupted(
+/*===============*/
+	dict_index_t*	index)		/*!< in/out: index */
+{
+	mem_heap_t*	heap;
+	mtr_t		mtr;
+	dict_index_t*	sys_index;
+	dtuple_t*	tuple;
+	dfield_t*	dfield;
+	byte*		buf;
+	const char*	status;
+	btr_cur_t	cursor;
+
+	ut_ad(index);
+	ut_ad(mutex_own(&dict_sys->mutex));
+	ut_ad(!dict_table_is_comp(dict_sys->sys_tables));
+	ut_ad(!dict_table_is_comp(dict_sys->sys_indexes));
+
+#ifdef UNIV_SYNC_DEBUG
+        ut_ad(sync_thread_levels_empty_except_dict());
+#endif
+
+	/* Mark the table as corrupted only if the clustered index
+	is corrupted */
+	if (dict_index_is_clust(index)) {
+		index->table->corrupted = TRUE;
+	}
+
+	if (UNIV_UNLIKELY(dict_index_is_corrupted(index))) {
+		/* The index was already flagged corrupted. */
+		ut_ad(index->table->corrupted);
+		return;
+	}
+
+	heap = mem_heap_create(sizeof(dtuple_t) + 2 * (sizeof(dfield_t)
+			       + sizeof(que_fork_t) + sizeof(upd_node_t)
+			       + sizeof(upd_t) + 12));
+	mtr_start(&mtr);
+	index->type |= DICT_CORRUPT;
+
+	sys_index = UT_LIST_GET_FIRST(dict_sys->sys_indexes->indexes);
+
+	/* Find the index row in SYS_INDEXES */
+	tuple = dtuple_create(heap, 2);
+
+	dfield = dtuple_get_nth_field(tuple, 0);
+	buf = mem_heap_alloc(heap, 8);
+	mach_write_to_8(buf, index->table->id);
+	dfield_set_data(dfield, buf, 8);
+
+	dfield = dtuple_get_nth_field(tuple, 1);
+	buf = mem_heap_alloc(heap, 8);
+	mach_write_to_8(buf, index->id);
+	dfield_set_data(dfield, buf, 8);
+
+	dict_index_copy_types(tuple, sys_index, 2);
+
+	btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_GE,
+				    BTR_MODIFY_LEAF,
+				    &cursor, 0, __FILE__, __LINE__, &mtr);
+
+	if (cursor.up_match == dtuple_get_n_fields(tuple)) {
+		/* UPDATE SYS_INDEXES SET TYPE=index->type
+		WHERE TABLE_ID=index->table->id AND INDEX_ID=index->id */
+		ulint	len;
+		byte*	field	= rec_get_nth_field_old(
+			btr_cur_get_rec(&cursor),
+			DICT_SYS_INDEXES_TYPE_FIELD, &len);
+		if (len != 4) {
+			goto fail;
+		}
+		mlog_write_ulint(field, index->type, MLOG_4BYTES, &mtr);
+		status = "  InnoDB: Flagged corruption of ";
+	} else {
+fail:
+		status = "  InnoDB: Unable to flag corruption of ";
+	}
+
+	mtr_commit(&mtr);
+	mem_heap_free(heap);
+
+	ut_print_timestamp(stderr);
+	fputs(status, stderr);
+	dict_index_name_print(stderr, NULL, index);
+	putc('\n', stderr);
+}
+
+/**********************************************************************//**
+Flags an index corrupted in the data dictionary cache only. This
+is used mostly to mark a corrupted index when index's own dictionary
+is corrupted, and we force to load such index for repair purpose */
+UNIV_INTERN
+void
+dict_set_corrupted_index_cache_only(
+/*================================*/
+	dict_index_t*	index)		/*!< in/out: index */
+{
+	ut_ad(index);
+	ut_ad(mutex_own(&dict_sys->mutex));
+	ut_ad(!dict_table_is_comp(dict_sys->sys_tables));
+	ut_ad(!dict_table_is_comp(dict_sys->sys_indexes));
+
+	/* Mark the table as corrupted only if the clustered index
+	is corrupted */
+	if (dict_index_is_clust(index)) {
+		index->table->corrupted = TRUE;
+	}
+
+	index->type |= DICT_CORRUPT;
+}
 #endif /* !UNIV_HOTBACKUP */

=== modified file 'storage/innobase/dict/dict0load.c'
--- a/storage/innobase/dict/dict0load.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/dict/dict0load.c	2011-08-17 01:07:59 +0000
@@ -52,6 +52,11 @@ static const char* SYSTEM_TABLE_NAME[] =
 	"SYS_FOREIGN",
 	"SYS_FOREIGN_COLS"
 };
+
+/* If this flag is TRUE, then we will load the cluster index's (and tables')
+metadata even if it is marked as "corrupted". */
+UNIV_INTERN my_bool     srv_load_corrupted = FALSE;
+
 /****************************************************************//**
 Compare the name of an index column.
 @return	TRUE if the i'th column of index is 'name'. */
@@ -1324,6 +1329,9 @@ err_len:
 		goto err_len;
 	}
 	type = mach_read_from_4(field);
+	if (UNIV_UNLIKELY(type & (~0 << DICT_IT_BITS))) {
+		return("unknown SYS_INDEXES.TYPE bits");
+	}
 
 	field = rec_get_nth_field_old(rec, 7/*SPACE*/, &len);
 	if (UNIV_UNLIKELY(len != 4)) {
@@ -1423,16 +1431,47 @@ dict_load_indexes(
 			goto next_rec;
 		} else if (err_msg) {
 			fprintf(stderr, "InnoDB: %s\n", err_msg);
+			if (ignore_err & DICT_ERR_IGNORE_CORRUPT) {
+				goto next_rec;
+			}
 			error = DB_CORRUPTION;
 			goto func_exit;
 		}
 
 		ut_ad(index);
 
+		/* Check whether the index is corrupted */
+		if (dict_index_is_corrupted(index)) {
+			ut_print_timestamp(stderr);
+			fputs("  InnoDB: ", stderr);
+			dict_index_name_print(stderr, NULL, index);
+			fputs(" is corrupted\n", stderr);
+
+			if (!srv_load_corrupted
+			    && !(ignore_err & DICT_ERR_IGNORE_CORRUPT)
+			    && dict_index_is_clust(index)) {
+				dict_mem_index_free(index);
+
+				error = DB_INDEX_CORRUPT;
+				goto func_exit;
+			} else {
+				/* We will load the index if
+				1) srv_load_corrupted is TRUE
+				2) ignore_err is set with
+				DICT_ERR_IGNORE_CORRUPT
+				3) if the index corrupted is a secondary
+				index */
+				ut_print_timestamp(stderr);
+				fputs("  InnoDB: load corrupted index ", stderr);
+				dict_index_name_print(stderr, NULL, index);
+				putc('\n', stderr);
+			}
+		}
+
 		/* We check for unsupported types first, so that the
 		subsequent checks are relevant for the supported types. */
-		if (index->type & ~(DICT_CLUSTERED | DICT_UNIQUE)) {
-
+		if (index->type & ~(DICT_CLUSTERED | DICT_UNIQUE
+				    | DICT_CORRUPT)) {
 			fprintf(stderr,
 				"InnoDB: Error: unknown type %lu"
 				" of index %s of table %s\n",
@@ -1453,9 +1492,13 @@ dict_load_indexes(
 				/* If caller can tolerate this error,
 				we will continue to load the index and
 				let caller deal with this error. However
-				mark the index and table corrupted */
-				index->corrupted = TRUE;
-				table->corrupted = TRUE;
+				mark the index and table corrupted. We
+				only need to mark such in the index
+				dictionary cache for such metadata corruption,
+				since we would always be able to set it
+				when loading the dictionary cache */
+				dict_set_corrupted_index_cache_only(index);
+
 				fprintf(stderr,
 					"InnoDB: Index is corrupt but forcing"
 					" load into data dictionary\n");
@@ -1495,9 +1538,10 @@ corrupted:
 					index->name, table->name);
 
 				/* If the force recovery flag is set, and
-				if the failed index is not the primary index, we
-				will continue and open other indexes */
-				if (srv_force_recovery
+				if the failed index is not the clustered index,
+				we will continue and open other indexes */
+				if ((srv_force_recovery
+				     || srv_load_corrupted)
 				    && !dict_index_is_clust(index)) {
 					error = DB_SUCCESS;
 					goto next_rec;
@@ -1812,6 +1856,30 @@ err_exit:
 
 	err = dict_load_indexes(table, heap, ignore_err);
 
+	if (err == DB_INDEX_CORRUPT) {
+		/* Refuse to load the table if the table has a corrupted
+		cluster index */
+		if (!srv_load_corrupted) {
+			fprintf(stderr, "InnoDB: Error: Load table ");
+			ut_print_name(stderr, NULL, TRUE, table->name);
+			fprintf(stderr, " failed, the table has corrupted"
+					" clustered indexes. Turn on"
+					" 'innodb_force_load_corrupted'"
+					" to drop it\n");
+
+			dict_table_remove_from_cache(table);
+			table = NULL;
+			goto func_exit;
+		} else {
+			dict_index_t*	clust_index;
+			clust_index = dict_table_get_first_index(table);
+
+			if (dict_index_is_corrupted(clust_index)) {
+				table->corrupted = TRUE;
+			}
+		}
+	}
+
 	/* Initialize table foreign_child value. Its value could be
 	changed when dict_load_foreigns() is called below */
 	table->fk_max_recusive_level = 0;
@@ -1838,9 +1906,15 @@ err_exit:
 		index = dict_table_get_first_index(table);
 
 		if (!srv_force_recovery || !index
-		     || !dict_index_is_clust(index)) {
+		    || !dict_index_is_clust(index)) {
 			dict_table_remove_from_cache(table);
 			table = NULL;
+		} else if (dict_index_is_corrupted(index)) {
+
+			/* It is possible we force to load a corrupted
+			clustered index if srv_load_corrupted is set.
+			Mark the table as corrupted in this case */
+			table->corrupted = TRUE;
 		}
 	}
 #if 0
@@ -1867,6 +1941,7 @@ err_exit:
 		mutex_exit(&dict_foreign_err_mutex);
 	}
 #endif /* 0 */
+func_exit:
 	mem_heap_free(heap);
 
 	return(table);

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2011-07-19 14:54:59 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-08-17 01:07:59 +0000
@@ -1043,6 +1043,8 @@ convert_error_code_to_mysql(
 #endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 	case DB_UNSUPPORTED:
 		return(HA_ERR_UNSUPPORTED);
+	case DB_INDEX_CORRUPT:
+		return(HA_ERR_INDEX_CORRUPT);
 	}
 }
 
@@ -2078,6 +2080,27 @@ no_db_name:
 
 }
 
+/*****************************************************************//**
+A wrapper function of innobase_convert_name(), convert a table or
+index name to the MySQL system_charset_info (UTF-8) and quote it if needed.
+@return	pointer to the end of buf */
+static inline
+void
+innobase_format_name(
+/*==================*/
+	char*		buf,	/*!< out: buffer for converted identifier */
+	ulint		buflen,	/*!< in: length of buf, in bytes */
+	const char*	name,	/*!< in: index or table name to format */
+	ibool		is_index_name) /*!< in: index name */
+{
+	const char*     bufend;
+
+	bufend = innobase_convert_name(buf, buflen, name, strlen(name),
+				       NULL, is_index_name);
+
+	buf[bufend - buf] = '\0';
+}
+
 /**********************************************************************//**
 Determines if the currently running transaction has been interrupted.
 @return	TRUE if interrupted */
@@ -5664,12 +5687,14 @@ ha_innobase::index_read(
 
 	index = prebuilt->index;
 
-	if (UNIV_UNLIKELY(index == NULL)) {
+	if (UNIV_UNLIKELY(index == NULL) || dict_index_is_corrupted(index)) {
 		prebuilt->index_usable = FALSE;
 		DBUG_RETURN(HA_ERR_CRASHED);
 	}
 	if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
-		DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED);
+		DBUG_RETURN(dict_index_is_corrupted(index)
+			    ? HA_ERR_INDEX_CORRUPT
+			    : HA_ERR_TABLE_DEF_CHANGED);
 	}
 
 	/* Note that if the index for which the search template is built is not
@@ -5855,10 +5880,33 @@ ha_innobase::change_active_index(
 							   prebuilt->index);
 
 	if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
-		push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-				    HA_ERR_TABLE_DEF_CHANGED,
-				    "InnoDB: insufficient history for index %u",
-				    keynr);
+		if (dict_index_is_corrupted(prebuilt->index)) {
+			char	index_name[MAX_FULL_NAME_LEN + 1];
+			char	table_name[MAX_FULL_NAME_LEN + 1];
+
+			innobase_format_name(
+				index_name, sizeof index_name,
+				prebuilt->index->name, TRUE);
+
+			innobase_format_name(
+				table_name, sizeof table_name,
+				prebuilt->index->table->name, FALSE);
+
+			push_warning_printf(
+				user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+				HA_ERR_INDEX_CORRUPT,
+				"InnoDB: Index %s for table %s is"
+				" marked as corrupted",
+				index_name, table_name);
+			DBUG_RETURN(1);
+		} else {
+			push_warning_printf(
+				user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+				HA_ERR_TABLE_DEF_CHANGED,
+				"InnoDB: insufficient history for index %u",
+				keynr);
+		}
+
 		/* The caller seems to ignore this.  Thus, we must check
 		this again in row_search_for_mysql(). */
 		DBUG_RETURN(2);
@@ -7518,6 +7566,10 @@ ha_innobase::records_in_range(
 		n_rows = HA_POS_ERROR;
 		goto func_exit;
 	}
+	if (dict_index_is_corrupted(index)) {
+		n_rows = HA_ERR_INDEX_CORRUPT;
+		goto func_exit;
+	}
 	if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
 		n_rows = HA_ERR_TABLE_DEF_CHANGED;
 		goto func_exit;
@@ -7898,6 +7950,8 @@ ha_innobase::info_low(
 
 	if (flag & HA_STATUS_VARIABLE) {
 
+		ulint	page_size;
+
 		dict_table_stats_lock(ib_table, RW_S_LATCH);
 
 		n_rows = ib_table->stat_n_rows;
@@ -7940,14 +7994,19 @@ ha_innobase::info_low(
 			prebuilt->autoinc_last_value = 0;
 		}
 
+		page_size = dict_table_zip_size(ib_table);
+		if (page_size == 0) {
+			page_size = UNIV_PAGE_SIZE;
+		}
+
 		stats.records = (ha_rows)n_rows;
 		stats.deleted = 0;
-		stats.data_file_length = ((ulonglong)
-				ib_table->stat_clustered_index_size)
-					* UNIV_PAGE_SIZE;
-		stats.index_file_length = ((ulonglong)
-				ib_table->stat_sum_of_other_index_sizes)
-					* UNIV_PAGE_SIZE;
+		stats.data_file_length
+			= ((ulonglong) ib_table->stat_clustered_index_size)
+			* page_size;
+		stats.index_file_length =
+			((ulonglong) ib_table->stat_sum_of_other_index_sizes)
+			* page_size;
 
 		dict_table_stats_unlock(ib_table, RW_S_LATCH);
 
@@ -8177,6 +8236,7 @@ ha_innobase::check(
 	ulint		n_rows_in_table	= ULINT_UNDEFINED;
 	ibool		is_ok		= TRUE;
 	ulint		old_isolation_level;
+	ibool		table_corrupted;
 
 	DBUG_ENTER("ha_innobase::check");
 	DBUG_ASSERT(thd == ha_thd());
@@ -8218,6 +8278,14 @@ ha_innobase::check(
 
 	prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
 
+	/* Check whether the table is already marked as corrupted
+	before running the check table */
+	table_corrupted = prebuilt->table->corrupted;
+
+	/* Reset table->corrupted bit so that check table can proceed to
+	do additional check */
+	prebuilt->table->corrupted = FALSE;
+
 	/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
 	mutex_enter(&kernel_mutex);
 	srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
@@ -8226,6 +8294,7 @@ ha_innobase::check(
 	for (index = dict_table_get_first_index(prebuilt->table);
 	     index != NULL;
 	     index = dict_table_get_next_index(index)) {
+		char	index_name[MAX_FULL_NAME_LEN + 1];
 #if 0
 		fputs("Validating index ", stderr);
 		ut_print_name(stderr, trx, FALSE, index->name);
@@ -8234,11 +8303,16 @@ ha_innobase::check(
 
 		if (!btr_validate_index(index, prebuilt->trx)) {
 			is_ok = FALSE;
+
+			innobase_format_name(
+				index_name, sizeof index_name,
+				prebuilt->index->name, TRUE);
+
 			push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 					    ER_NOT_KEYFILE,
 					    "InnoDB: The B-tree of"
-					    " index '%-.200s' is corrupted.",
-					    index->name);
+					    " index %s is corrupted.",
+					    index_name);
 			continue;
 		}
 
@@ -8251,11 +8325,26 @@ ha_innobase::check(
 			prebuilt->trx, prebuilt->index);
 
 		if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
-			push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-					    HA_ERR_TABLE_DEF_CHANGED,
-					    "InnoDB: Insufficient history for"
-					    " index '%-.200s'",
-					    index->name);
+			innobase_format_name(
+				index_name, sizeof index_name,
+				prebuilt->index->name, TRUE);
+
+			if (dict_index_is_corrupted(prebuilt->index)) {
+				push_warning_printf(
+					user_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+					HA_ERR_INDEX_CORRUPT,
+					"InnoDB: Index %s is marked as"
+					" corrupted",
+					index_name);
+				is_ok = FALSE;
+			} else {
+				push_warning_printf(
+					thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+					HA_ERR_TABLE_DEF_CHANGED,
+					"InnoDB: Insufficient history for"
+					" index %s",
+					index_name);
+			}
 			continue;
 		}
 
@@ -8269,12 +8358,19 @@ ha_innobase::check(
 		prebuilt->select_lock_type = LOCK_NONE;
 
 		if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
+			innobase_format_name(
+				index_name, sizeof index_name,
+				index->name, TRUE);
+
 			push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 					    ER_NOT_KEYFILE,
 					    "InnoDB: The B-tree of"
-					    " index '%-.200s' is corrupted.",
-					    index->name);
+					    " index %s is corrupted.",
+					    index_name);
 			is_ok = FALSE;
+			row_mysql_lock_data_dictionary(prebuilt->trx);
+			dict_set_corrupted(index);
+			row_mysql_unlock_data_dictionary(prebuilt->trx);
 		}
 
 		if (thd_killed(user_thd)) {
@@ -8301,6 +8397,20 @@ ha_innobase::check(
 		}
 	}
 
+	if (table_corrupted) {
+		/* If some previous operation has marked the table as
+		corrupted in memory, and has not propagated such to
+		clustered index, we will do so here */
+		index = dict_table_get_first_index(prebuilt->table);
+
+		if (!dict_index_is_corrupted(index)) {
+			mutex_enter(&dict_sys->mutex);
+			dict_set_corrupted(index);
+			mutex_exit(&dict_sys->mutex);
+		}
+		prebuilt->table->corrupted = TRUE;
+	}
+
 	/* Restore the original isolation level */
 	prebuilt->trx->isolation_level = old_isolation_level;
 
@@ -11094,6 +11204,11 @@ static MYSQL_SYSVAR_BOOL(large_prefix, i
   "Support large index prefix length of REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes.",
   NULL, NULL, FALSE);
 
+static MYSQL_SYSVAR_BOOL(force_load_corrupted, srv_load_corrupted,
+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+  "Force InnoDB to load metadata of corrupted table.",
+  NULL, NULL, FALSE);
+
 static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
   "Force InnoDB to not use next-key locking, to use only row-level locking.",
@@ -11353,6 +11468,7 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(flush_method),
   MYSQL_SYSVAR(force_recovery),
   MYSQL_SYSVAR(large_prefix),
+  MYSQL_SYSVAR(force_load_corrupted),
   MYSQL_SYSVAR(locks_unsafe_for_binlog),
   MYSQL_SYSVAR(lock_wait_timeout),
 #ifdef UNIV_LOG_ARCHIVE

=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c	2011-05-04 09:08:07 +0000
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	2011-08-15 09:18:34 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -402,7 +402,7 @@ ibuf_tree_root_get(
 	block = buf_page_get(
 		IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr);
 
-	buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+	buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
 
 	root = buf_block_get_frame(block);
 
@@ -549,7 +549,7 @@ ibuf_init_at_db_start(void)
 		block = buf_page_get(
 			IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
 			RW_X_LATCH, &mtr);
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 
 		root = buf_block_get_frame(block);
 	}
@@ -2209,7 +2209,8 @@ ibuf_add_free_page(void)
 	} else {
 		buf_block_t*	block = buf_page_get(
 			IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
+
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
 
 		page = buf_block_get_frame(block);
 	}
@@ -2332,8 +2333,7 @@ ibuf_remove_free_page(void)
 		block = buf_page_get(
 			IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
-
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 
 		page = buf_block_get_frame(block);
 	}
@@ -3022,7 +3022,7 @@ ibuf_get_volume_buffered(
 			IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH,
 			mtr);
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 
 
 		prev_page = buf_block_get_frame(block);
@@ -3095,7 +3095,7 @@ count_later:
 			IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH,
 			mtr);
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 
 
 		next_page = buf_block_get_frame(block);
@@ -3333,7 +3333,7 @@ ibuf_set_entry_counter(
 				IBUF_SPACE_ID, 0, prev_page_no,
 				RW_X_LATCH, mtr);
 
-			buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+			buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 
 			prev_page = buf_block_get_frame(block);
 
@@ -4419,6 +4419,7 @@ ibuf_merge_or_delete_for_page(
 	ut_ad(!block || buf_block_get_space(block) == space);
 	ut_ad(!block || buf_block_get_page_no(block) == page_no);
 	ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
+	ut_ad(!block || buf_block_get_io_fix(block) == BUF_IO_READ);
 
 	if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE
 	    || trx_sys_hdr_page(space, page_no)) {
@@ -4571,7 +4572,13 @@ loop:
 
 		ut_a(success);
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		/* This is a user page (secondary index leaf page),
+		but we pretend that it is a change buffer page in
+		order to obey the latching order. This should be OK,
+		because buffered changes are applied immediately while
+		the block is io-fixed. Other threads must not try to
+		latch an io-fixed block. */
+		buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
 	}
 
 	/* Position pcur in the insert buffer at the first entry for this
@@ -4675,7 +4682,12 @@ loop:
 					__FILE__, __LINE__, &mtr);
 				ut_a(success);
 
-				buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+				/* This is a user page (secondary
+				index leaf page), but it should be OK
+				to use too low latching order for it,
+				as the block is io-fixed. */
+				buf_block_dbg_add_level(
+					block, SYNC_IBUF_TREE_NODE);
 
 				if (!ibuf_restore_pos(space, page_no,
 						      search_tuple,

=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h	2011-06-16 09:07:49 +0000
+++ b/storage/innobase/include/btr0btr.h	2011-08-15 09:18:34 +0000
@@ -199,26 +199,45 @@ btr_block_get_func(
 	ulint		mode,		/*!< in: latch mode */
 	const char*	file,		/*!< in: file name */
 	ulint		line,		/*!< in: line where called */
-	mtr_t*		mtr)		/*!< in/out: mtr */
-	__attribute__((nonnull));
+# ifdef UNIV_SYNC_DEBUG
+	const dict_index_t*	index,	/*!< in: index tree, may be NULL
+					if it is not an insert buffer tree */
+# endif /* UNIV_SYNC_DEBUG */
+	mtr_t*		mtr);		/*!< in/out: mini-transaction */
+# ifdef UNIV_SYNC_DEBUG
+/** Gets a buffer page and declares its latching order level.
+@param space	tablespace identifier
+@param zip_size	compressed page size in bytes or 0 for uncompressed pages
+@param page_no	page number
+@param mode	latch mode
+@param index	index tree, may be NULL if not the insert buffer tree
+@param mtr	mini-transaction handle
+@return the block descriptor */
+#  define btr_block_get(space,zip_size,page_no,mode,index,mtr)	\
+	btr_block_get_func(space,zip_size,page_no,mode,		\
+			   __FILE__,__LINE__,index,mtr)
+# else /* UNIV_SYNC_DEBUG */
 /** Gets a buffer page and declares its latching order level.
 @param space	tablespace identifier
 @param zip_size	compressed page size in bytes or 0 for uncompressed pages
 @param page_no	page number
 @param mode	latch mode
+@param idx	index tree, may be NULL if not the insert buffer tree
 @param mtr	mini-transaction handle
 @return the block descriptor */
-# define btr_block_get(space,zip_size,page_no,mode,mtr) \
+#  define btr_block_get(space,zip_size,page_no,mode,idx,mtr)		\
 	btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr)
+# endif /* UNIV_SYNC_DEBUG */
 /** Gets a buffer page and declares its latching order level.
 @param space	tablespace identifier
 @param zip_size	compressed page size in bytes or 0 for uncompressed pages
 @param page_no	page number
 @param mode	latch mode
+@param idx	index tree, may be NULL if not the insert buffer tree
 @param mtr	mini-transaction handle
 @return the uncompressed page frame */
-# define btr_page_get(space,zip_size,page_no,mode,mtr) \
-	buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr))
+# define btr_page_get(space,zip_size,page_no,mode,idx,mtr)		\
+	buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,idx,mtr))
 #endif /* !UNIV_HOTBACKUP */
 /**************************************************************//**
 Gets the index id field of a page.
@@ -344,8 +363,7 @@ btr_free_root(
 	ulint	zip_size,	/*!< in: compressed page size in bytes
 				or 0 for uncompressed pages */
 	ulint	root_page_no,	/*!< in: root page number */
-	mtr_t*	mtr);		/*!< in: a mini-transaction which has already
-				been started */
+	mtr_t*	mtr);		/*!< in/out: mini-transaction */
 /*************************************************************//**
 Makes tree one level higher by splitting the root, and inserts
 the tuple. It is assumed that mtr contains an x-latch on the tree.

=== modified file 'storage/innobase/include/btr0btr.ic'
--- a/storage/innobase/include/btr0btr.ic	2010-11-03 09:25:14 +0000
+++ b/storage/innobase/include/btr0btr.ic	2011-08-15 09:18:34 +0000
@@ -1,6 +1,6 @@
 /*****************************************************************************
 
-Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -48,6 +48,10 @@ btr_block_get_func(
 	ulint		mode,		/*!< in: latch mode */
 	const char*	file,		/*!< in: file name */
 	ulint		line,		/*!< in: line where called */
+#ifdef UNIV_SYNC_DEBUG
+	const dict_index_t*	index,	/*!< in: index tree, may be NULL
+					if it is not an insert buffer tree */
+#endif /* UNIV_SYNC_DEBUG */
 	mtr_t*		mtr)		/*!< in/out: mtr */
 {
 	buf_block_t*	block;
@@ -57,7 +61,9 @@ btr_block_get_func(
 
 	if (mode != RW_NO_LATCH) {
 
-		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
+		buf_block_dbg_add_level(
+			block, index != NULL && dict_index_is_ibuf(index)
+			? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
 	}
 
 	return(block);

=== modified file 'storage/innobase/include/buf0lru.h'
--- a/storage/innobase/include/buf0lru.h	2011-07-19 14:54:59 +0000
+++ b/storage/innobase/include/buf0lru.h	2011-08-17 01:07:59 +0000
@@ -203,6 +203,17 @@ void
 buf_LRU_stat_update(void);
 /*=====================*/
 
+/******************************************************************//**
+Remove one page from LRU list and put it to free list */
+UNIV_INTERN
+void
+buf_LRU_free_one_page(
+/*==================*/
+	buf_page_t*	bpage)	/*!< in/out: block, must contain a file page and
+				be in a state where it can be freed; there
+				may or may not be a hash index to the page */
+	__attribute__((nonnull));
+
 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
 /**********************************************************************//**
 Validates the LRU list.

=== modified file 'storage/innobase/include/db0err.h'
--- a/storage/innobase/include/db0err.h	2011-06-28 12:28:21 +0000
+++ b/storage/innobase/include/db0err.h	2011-08-17 01:07:59 +0000
@@ -110,6 +110,7 @@ enum db_err {
 					foreign keys as its prefix columns */
 	DB_TOO_BIG_INDEX_COL,		/* index column size exceeds maximum
 					limit */
+	DB_INDEX_CORRUPT,		/* we have corrupted index */
 
 	/* The following are partial failure codes */
 	DB_FAIL = 1000,

=== modified file 'storage/innobase/include/dict0boot.h'
--- a/storage/innobase/include/dict0boot.h	2010-07-21 14:22:29 +0000
+++ b/storage/innobase/include/dict0boot.h	2011-08-17 01:07:59 +0000
@@ -137,8 +137,10 @@ dict_create(void);
 					header is created */
 /*-------------------------------------------------------------*/
 
-/* The field number of the page number field in the sys_indexes table
-clustered index */
+/* The field numbers in the SYS_TABLES clustered index */
+#define DICT_SYS_TABLES_TYPE_FIELD		5
+
+/* The field numbers in the SYS_INDEXES clustered index */
 #define DICT_SYS_INDEXES_PAGE_NO_FIELD	 8
 #define DICT_SYS_INDEXES_SPACE_NO_FIELD	 7
 #define DICT_SYS_INDEXES_TYPE_FIELD	 6

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/include/dict0dict.h	2011-08-17 01:07:59 +0000
@@ -585,6 +585,20 @@ dict_table_get_next_index(
 # define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index)
 #endif /* UNIV_DEBUG */
 #endif /* !UNIV_HOTBACKUP */
+
+/* Skip corrupted index */
+#define dict_table_skip_corrupt_index(index)			\
+	while (index && dict_index_is_corrupted(index)) {	\
+		index = dict_table_get_next_index(index);	\
+	}
+
+/* Get the next non-corrupt index */
+#define dict_table_next_uncorrupted_index(index)		\
+do {								\
+	index = dict_table_get_next_index(index);		\
+	dict_table_skip_corrupt_index(index);			\
+} while (0)
+
 /********************************************************************//**
 Check whether the index is the clustered index.
 @return	nonzero for clustered index, zero for other indexes */
@@ -593,7 +607,7 @@ ulint
 dict_index_is_clust(
 /*================*/
 	const dict_index_t*	index)	/*!< in: index */
-	__attribute__((pure));
+	__attribute__((nonnull, pure, warn_unused_result));
 /********************************************************************//**
 Check whether the index is unique.
 @return	nonzero for unique index, zero for other indexes */
@@ -602,7 +616,7 @@ ulint
 dict_index_is_unique(
 /*=================*/
 	const dict_index_t*	index)	/*!< in: index */
-	__attribute__((pure));
+	__attribute__((nonnull, pure, warn_unused_result));
 /********************************************************************//**
 Check whether the index is the insert buffer tree.
 @return	nonzero for insert buffer, zero for other indexes */
@@ -611,7 +625,7 @@ ulint
 dict_index_is_ibuf(
 /*===============*/
 	const dict_index_t*	index)	/*!< in: index */
-	__attribute__((pure));
+	__attribute__((nonnull, pure, warn_unused_result));
 /********************************************************************//**
 Check whether the index is a secondary index or the insert buffer tree.
 @return	nonzero for insert buffer, zero for other indexes */
@@ -620,7 +634,7 @@ ulint
 dict_index_is_sec_or_ibuf(
 /*======================*/
 	const dict_index_t*	index)	/*!< in: index */
-	__attribute__((pure));
+	__attribute__((nonnull, pure, warn_unused_result));
 
 /********************************************************************//**
 Gets the number of user-defined columns in a table in the dictionary
@@ -630,7 +644,8 @@ UNIV_INLINE
 ulint
 dict_table_get_n_user_cols(
 /*=======================*/
-	const dict_table_t*	table);	/*!< in: table */
+	const dict_table_t*	table)	/*!< in: table */
+	__attribute__((nonnull, pure, warn_unused_result));
 /********************************************************************//**
 Gets the number of system columns in a table in the dictionary cache.
 @return	number of system (e.g., ROW_ID) columns of a table */
@@ -638,7 +653,8 @@ UNIV_INLINE
 ulint
 dict_table_get_n_sys_cols(
 /*======================*/
-	const dict_table_t*	table);	/*!< in: table */
+	const dict_table_t*	table)	/*!< in: table */
+	__attribute__((nonnull, pure, warn_unused_result));
 /********************************************************************//**
 Gets the number of all columns (also system) in a table in the dictionary
 cache.
@@ -647,7 +663,8 @@ UNIV_INLINE
 ulint
 dict_table_get_n_cols(
 /*==================*/
-	const dict_table_t*	table);	/*!< in: table */
+	const dict_table_t*	table)	/*!< in: table */
+	__attribute__((nonnull, pure, warn_unused_result));
 #ifdef UNIV_DEBUG
 /********************************************************************//**
 Gets the nth column of a table.
@@ -1243,6 +1260,56 @@ void
 dict_close(void);
 /*============*/
 
+/**********************************************************************//**
+Check whether the table is corrupted.
+@return	nonzero for corrupted table, zero for valid tables */
+UNIV_INLINE
+ulint
+dict_table_is_corrupted(
+/*====================*/
+	const dict_table_t*	table)	/*!< in: table */
+	__attribute__((nonnull, pure, warn_unused_result));
+
+/**********************************************************************//**
+Check whether the index is corrupted.
+@return	nonzero for corrupted index, zero for valid indexes */
+UNIV_INLINE
+ulint
+dict_index_is_corrupted(
+/*====================*/
+	const dict_index_t*	index)	/*!< in: index */
+	__attribute__((nonnull, pure, warn_unused_result));
+
+/**********************************************************************//**
+Flags an index and table corrupted both in the data dictionary cache
+and in the system table SYS_INDEXES. */
+UNIV_INTERN
+void
+dict_set_corrupted(
+/*===============*/
+	dict_index_t*	index)		/*!< in/out: index */
+	UNIV_COLD __attribute__((nonnull));
+
+/**********************************************************************//**
+Flags an index corrupted in the data dictionary cache only. This
+is used mostly to mark a corrupted index when index's own dictionary
+is corrupted, and we force to load such index for repair purpose */
+UNIV_INTERN
+void
+dict_set_corrupted_index_cache_only(
+/*================================*/
+	dict_index_t*	index);		/*!< in/out: index */
+
+/**********************************************************************//**
+Flags a table with specified space_id corrupted in the table dictionary
+cache.
+@return TRUE if successful */
+UNIV_INTERN
+ibool
+dict_set_corrupted_by_space(
+/*========================*/
+	ulint		space_id);	/*!< in: space ID */
+
 #ifndef UNIV_NONINL
 #include "dict0dict.ic"
 #endif

=== modified file 'storage/innobase/include/dict0dict.ic'
--- a/storage/innobase/include/dict0dict.ic	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/include/dict0dict.ic	2011-08-17 01:07:59 +0000
@@ -27,6 +27,7 @@ Created 1/8/1996 Heikki Tuuri
 #ifndef UNIV_HOTBACKUP
 #include "dict0load.h"
 #include "rem0types.h"
+#include "srv0srv.h"
 
 /*********************************************************************//**
 Gets the minimum number of bytes per character.
@@ -828,7 +829,7 @@ dict_table_check_if_in_cache_low(
 }
 
 /**********************************************************************//**
-load a table into dictionary cache, ignore any error specified during load; 
+load a table into dictionary cache, ignore any error specified during load;
 @return	table, NULL if not found */
 UNIV_INLINE
 dict_table_t*
@@ -872,6 +873,18 @@ dict_table_get_low(
 
 	table = dict_table_check_if_in_cache_low(table_name);
 
+	if (table && table->corrupted) {
+		fprintf(stderr, "InnoDB: table");
+		ut_print_name(stderr, NULL, TRUE, table->name);
+		if (srv_load_corrupted) {
+			fputs(" is corrupted, but"
+			      " innodb_force_load_corrupted is set\n", stderr);
+		} else {
+			fputs(" is corrupted\n", stderr);
+			return(NULL);
+		}
+	}
+
 	if (table == NULL) {
 		table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE);
 	}
@@ -937,4 +950,35 @@ dict_max_field_len_store_undo(
 	return(prefix_len);
 }
 
+/********************************************************************//**
+Check whether the table is corrupted.
+@return	nonzero for corrupted table, zero for valid tables */
+UNIV_INLINE
+ulint
+dict_table_is_corrupted(
+/*====================*/
+	const dict_table_t*	table)	/*!< in: table */
+{
+	ut_ad(table);
+	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+	return(UNIV_UNLIKELY(table->corrupted));
+}
+
+/********************************************************************//**
+Check whether the index is corrupted.
+@return	nonzero for corrupted index, zero for valid indexes */
+UNIV_INLINE
+ulint
+dict_index_is_corrupted(
+/*====================*/
+	const dict_index_t*	index)	/*!< in: index */
+{
+	ut_ad(index);
+	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+	return(UNIV_UNLIKELY((index->type & DICT_CORRUPT)
+	       || (index->table && index->table->corrupted)));
+}
+
 #endif /* !UNIV_HOTBACKUP */

=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/include/dict0mem.h	2011-08-17 01:07:59 +0000
@@ -51,7 +51,12 @@ combination of types */
 #define DICT_UNIQUE	2	/*!< unique index */
 #define	DICT_UNIVERSAL	4	/*!< index which can contain records from any
 				other index */
-#define	DICT_IBUF 	8	/*!< insert buffer tree */
+#define	DICT_IBUF	8	/*!< insert buffer tree */
+#define	DICT_CORRUPT	16	/*!< bit to store the corrupted flag
+				in SYS_INDEXES.TYPE */
+
+#define	DICT_IT_BITS	5	/*!< number of bits used for
+				SYS_INDEXES.TYPE */
 /* @} */
 
 /** Types for a table object */
@@ -369,8 +374,9 @@ struct dict_index_struct{
 				/*!< space where the index tree is placed */
 	unsigned	page:32;/*!< index tree root page number */
 #endif /* !UNIV_HOTBACKUP */
-	unsigned	type:4;	/*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
-				DICT_UNIVERSAL, DICT_IBUF) */
+	unsigned	type:DICT_IT_BITS;
+				/*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
+				DICT_UNIVERSAL, DICT_IBUF, DICT_CORRUPT) */
 	unsigned	trx_id_offset:10;/*!< position of the trx id column
 				in a clustered index record, if the fields
 				before it are known to be of a fixed size,
@@ -391,8 +397,6 @@ struct dict_index_struct{
 				/*!< TRUE if this index is marked to be
 				dropped in ha_innobase::prepare_drop_index(),
 				otherwise FALSE */
-	unsigned	corrupted:1;
-				/*!< TRUE if the index object is corrupted */
 	dict_field_t*	fields;	/*!< array of field descriptions */
 #ifndef UNIV_HOTBACKUP
 	UT_LIST_NODE_T(dict_index_t)

=== modified file 'storage/innobase/include/dict0types.h'
--- a/storage/innobase/include/dict0types.h	2011-02-09 09:15:06 +0000
+++ b/storage/innobase/include/dict0types.h	2011-08-17 01:07:59 +0000
@@ -51,7 +51,8 @@ be or-ed together */
 enum dict_err_ignore {
         DICT_ERR_IGNORE_NONE = 0,        /*!< no error to ignore */
         DICT_ERR_IGNORE_INDEX_ROOT = 1, /*!< ignore error if index root
-					page is FIL_NUL or incorrect value */
+					page is FIL_NULL or incorrect value */
+	DICT_ERR_IGNORE_CORRUPT = 2,	/*!< skip corrupted indexes */
         DICT_ERR_IGNORE_ALL = 0xFFFF	/*!< ignore all errors */
 };
 

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	2011-07-19 14:54:59 +0000
+++ b/storage/innobase/include/srv0srv.h	2011-08-17 01:07:59 +0000
@@ -141,6 +141,10 @@ extern ulint	srv_log_buffer_size;
 extern ulong	srv_flush_log_at_trx_commit;
 extern char	srv_adaptive_flushing;
 
+/* If this flag is TRUE, then we will load the indexes' (and tables') metadata
+even if they are marked as "corrupted". Mostly it is for DBA to process
+corrupted index and table */
+extern my_bool	srv_load_corrupted;
 
 /* The sort order table of the MySQL latin1_swedish_ci character set
 collation */

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	2011-06-16 09:07:49 +0000
+++ b/storage/innobase/include/sync0sync.h	2011-08-15 09:18:34 +0000
@@ -638,10 +638,6 @@ or row lock! */
 #define SYNC_DICT_HEADER	995
 #define SYNC_IBUF_HEADER	914
 #define SYNC_IBUF_PESS_INSERT_MUTEX 912
-#define SYNC_IBUF_MUTEX		910	/* ibuf mutex is really below
-					SYNC_FSP_PAGE: we assign a value this
-					high only to make the program to pass
-					the debug checks */
 /*-------------------------------*/
 #define	SYNC_INDEX_TREE		900
 #define SYNC_TREE_NODE_NEW	892
@@ -657,8 +653,11 @@ or row lock! */
 #define	SYNC_FSP		400
 #define	SYNC_FSP_PAGE		395
 /*------------------------------------- Insert buffer headers */
-/*------------------------------------- ibuf_mutex */
+#define SYNC_IBUF_MUTEX		370	/* ibuf_mutex */
 /*------------------------------------- Insert buffer tree */
+#define SYNC_IBUF_INDEX_TREE	360
+#define SYNC_IBUF_TREE_NODE_NEW	359
+#define SYNC_IBUF_TREE_NODE	358
 #define	SYNC_IBUF_BITMAP_MUTEX	351
 #define	SYNC_IBUF_BITMAP	350
 /*------------------------------------- MySQL query cache mutex */

=== modified file 'storage/innobase/pars/pars0opt.c'
--- a/storage/innobase/pars/pars0opt.c	2010-06-22 15:58:28 +0000
+++ b/storage/innobase/pars/pars0opt.c	2011-08-17 01:07:59 +0000
@@ -568,7 +568,7 @@ opt_search_plan_for_table(
 			best_last_op = last_op;
 		}
 
-		index = dict_table_get_next_index(index);
+		dict_table_next_uncorrupted_index(index);
 	}
 
 	plan->index = best_index;

=== modified file 'storage/innobase/row/row0ins.c'
--- a/storage/innobase/row/row0ins.c	2011-06-16 09:07:49 +0000
+++ b/storage/innobase/row/row0ins.c	2011-08-17 01:07:59 +0000
@@ -118,6 +118,9 @@ ins_node_create_entry_list(
 					      node->entry_sys_heap);
 		UT_LIST_ADD_LAST(tuple_list, node->entry_list, entry);
 
+		/* We will include all indexes (include those corrupted
+		secondary indexes) in the entry list. Filteration of
+		these corrupted index will be done in row_ins() */
 		index = dict_table_get_next_index(index);
 	}
 }
@@ -2046,7 +2049,6 @@ row_ins_index_entry_low(
 			mtr_start(&mtr);
 
 			if (err != DB_SUCCESS) {
-
 				goto function_exit;
 			}
 
@@ -2431,6 +2433,13 @@ row_ins(
 
 		node->index = dict_table_get_next_index(node->index);
 		node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
+
+		/* Skip corrupted secondar index and its entry */
+		while (node->index && dict_index_is_corrupted(node->index)) {
+
+			node->index = dict_table_get_next_index(node->index);
+			node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);
+		}
 	}
 
 	ut_ad(node->entry == NULL);

=== modified file 'storage/innobase/row/row0merge.c'
--- a/storage/innobase/row/row0merge.c	2011-05-04 09:08:07 +0000
+++ b/storage/innobase/row/row0merge.c	2011-08-17 01:07:59 +0000
@@ -2554,8 +2554,9 @@ row_merge_is_index_usable(
 	const trx_t*		trx,	/*!< in: transaction */
 	const dict_index_t*	index)	/*!< in: index to check */
 {
-	return(!trx->read_view
-	       || read_view_sees_trx_id(trx->read_view, index->trx_id));
+	return(!dict_index_is_corrupted(index)
+	       && (!trx->read_view
+	           || read_view_sees_trx_id(trx->read_view, index->trx_id)));
 }
 
 /*********************************************************************//**

=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c	2011-06-28 12:28:21 +0000
+++ b/storage/innobase/row/row0mysql.c	2011-08-17 01:07:59 +0000
@@ -3098,7 +3098,8 @@ row_drop_table_for_mysql(
 	ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
 
-	table = dict_table_get_low_ignore_err(name, DICT_ERR_IGNORE_INDEX_ROOT);
+	table = dict_table_get_low_ignore_err(
+		name, DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT);
 
 	if (!table) {
 		err = DB_TABLE_NOT_FOUND;

=== modified file 'storage/innobase/row/row0purge.c'
--- a/storage/innobase/row/row0purge.c	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/row/row0purge.c	2011-08-17 01:07:59 +0000
@@ -469,6 +469,13 @@ row_purge_del_mark(
 	heap = mem_heap_create(1024);
 
 	while (node->index != NULL) {
+		/* skip corrupted secondary index */
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		index = node->index;
 
 		/* Build the index entry */
@@ -516,6 +523,12 @@ row_purge_upd_exist_or_extern_func(
 	heap = mem_heap_create(1024);
 
 	while (node->index != NULL) {
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		index = node->index;
 
 		if (row_upd_changes_ord_field_binary(node->index, node->update,

=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c	2011-05-31 09:12:32 +0000
+++ b/storage/innobase/row/row0sel.c	2011-08-17 01:07:59 +0000
@@ -2541,6 +2541,8 @@ row_sel_field_store_in_mysql_format(
 
 	ut_ad(len != UNIV_SQL_NULL);
 	UNIV_MEM_ASSERT_RW(data, len);
+	UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len);
+	UNIV_MEM_INVALID(dest, templ->mysql_col_len);
 
 	switch (templ->type) {
 		const byte*	field_end;
@@ -2579,14 +2581,16 @@ row_sel_field_store_in_mysql_format(
 
 			dest = row_mysql_store_true_var_len(
 				dest, len, templ->mysql_length_bytes);
+			/* Copy the actual data. Leave the rest of the
+			buffer uninitialized. */
+			memcpy(dest, data, len);
+			break;
 		}
 
 		/* Copy the actual data */
 		ut_memcpy(dest, data, len);
 
-		/* Pad with trailing spaces. We pad with spaces also the
-		unused end of a >= 5.0.3 true VARCHAR column, just in case
-		MySQL expects its contents to be deterministic. */
+		/* Pad with trailing spaces. */
 
 		pad = dest + len;
 
@@ -3113,6 +3117,39 @@ sel_restore_position_for_mysql(
 }
 
 /********************************************************************//**
+Copies a cached field for MySQL from the fetch cache. */
+static
+void
+row_sel_copy_cached_field_for_mysql(
+/*================================*/
+	byte*			buf,	/*!< in/out: row buffer */
+	const byte*		cache,	/*!< in: cached row */
+	const mysql_row_templ_t*templ)	/*!< in: column template */
+{
+	ulint	len;
+
+	buf += templ->mysql_col_offset;
+	cache += templ->mysql_col_offset;
+
+	UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len);
+
+	if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR
+	    && templ->type != DATA_INT) {
+		/* Check for != DATA_INT to make sure we do
+		not treat MySQL ENUM or SET as a true VARCHAR!
+		Find the actual length of the true VARCHAR field. */
+		row_mysql_read_true_varchar(
+			&len, cache, templ->mysql_length_bytes);
+		len += templ->mysql_length_bytes;
+		UNIV_MEM_INVALID(buf, templ->mysql_col_len);
+	} else {
+		len = templ->mysql_col_len;
+	}
+
+	ut_memcpy(buf, cache, len);
+}
+
+/********************************************************************//**
 Pops a cached row for MySQL from the fetch cache. */
 UNIV_INLINE
 void
@@ -3124,26 +3161,22 @@ row_sel_pop_cached_row_for_mysql(
 {
 	ulint			i;
 	const mysql_row_templ_t*templ;
-	byte*			cached_rec;
+	const byte*		cached_rec;
 	ut_ad(prebuilt->n_fetch_cached > 0);
 	ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
 
+	UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len);
+
+	cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first];
+
 	if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread)) {
 		/* Copy cache record field by field, don't touch fields that
 		are not covered by current key */
-		cached_rec = prebuilt->fetch_cache[
-			prebuilt->fetch_cache_first];
 
 		for (i = 0; i < prebuilt->n_template; i++) {
 			templ = prebuilt->mysql_template + i;
-#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
-			UNIV_MEM_ASSERT_RW(cached_rec
-					   + templ->mysql_col_offset,
-					   templ->mysql_col_len);
-#endif
-			ut_memcpy(buf + templ->mysql_col_offset,
-				  cached_rec + templ->mysql_col_offset,
-				  templ->mysql_col_len);
+			row_sel_copy_cached_field_for_mysql(
+				buf, cached_rec, templ);
 			/* Copy NULL bit of the current field from cached_rec
 			to buf */
 			if (templ->mysql_null_bit_mask) {
@@ -3153,17 +3186,24 @@ row_sel_pop_cached_row_for_mysql(
 					& (byte)templ->mysql_null_bit_mask;
 			}
 		}
+	} else if (prebuilt->mysql_prefix_len > 63) {
+		/* The record is long. Copy it field by field, in case
+		there are some long VARCHAR column of which only a
+		small length is being used. */
+		UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len);
+
+		/* First copy the NULL bits. */
+		ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len);
+		/* Then copy the requested fields. */
+
+		for (i = 0; i < prebuilt->n_template; i++) {
+			row_sel_copy_cached_field_for_mysql(
+				buf, cached_rec, prebuilt->mysql_template + i);
+		}
+	} else {
+		ut_memcpy(buf, cached_rec, prebuilt->mysql_prefix_len);
 	}
-	else {
-#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
-		UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache
-				   [prebuilt->fetch_cache_first],
-				   prebuilt->mysql_prefix_len);
-#endif
-		ut_memcpy(buf,
-			  prebuilt->fetch_cache[prebuilt->fetch_cache_first],
-			  prebuilt->mysql_prefix_len);
-	}
+
 	prebuilt->n_fetch_cached--;
 	prebuilt->fetch_cache_first++;
 
@@ -3401,6 +3441,13 @@ row_search_for_mysql(
 		return(DB_MISSING_HISTORY);
 	}
 
+	if (dict_index_is_corrupted(index)) {
+#ifdef UNIV_SYNC_DEBUG
+		ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+		return(DB_CORRUPTION);
+	}
+
 	if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
 		fprintf(stderr,
 			"InnoDB: Error: trying to free a corrupt\n"

=== modified file 'storage/innobase/row/row0uins.c'
--- a/storage/innobase/row/row0uins.c	2010-07-21 14:22:29 +0000
+++ b/storage/innobase/row/row0uins.c	2011-08-17 01:07:59 +0000
@@ -328,6 +328,8 @@ row_undo_ins(
 	node->index = dict_table_get_next_index(
 		dict_table_get_first_index(node->table));
 
+	dict_table_skip_corrupt_index(node->index);
+
 	while (node->index != NULL) {
 		dtuple_t*	entry;
 		ulint		err;
@@ -355,7 +357,7 @@ row_undo_ins(
 			}
 		}
 
-		node->index = dict_table_get_next_index(node->index);
+		dict_table_next_uncorrupted_index(node->index);
 	}
 
 	log_free_check();

=== modified file 'storage/innobase/row/row0umod.c'
--- a/storage/innobase/row/row0umod.c	2011-02-02 13:58:01 +0000
+++ b/storage/innobase/row/row0umod.c	2011-08-17 01:07:59 +0000
@@ -573,6 +573,14 @@ row_undo_mod_upd_del_sec(
 	heap = mem_heap_create(1024);
 
 	while (node->index != NULL) {
+
+		/* Skip all corrupted secondary index */
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		index = node->index;
 
 		entry = row_build_index_entry(node->row, node->ext,
@@ -626,6 +634,13 @@ row_undo_mod_del_mark_sec(
 	heap = mem_heap_create(1024);
 
 	while (node->index != NULL) {
+		/* Skip all corrupted secondary index */
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		index = node->index;
 
 		entry = row_build_index_entry(node->row, node->ext,
@@ -677,6 +692,13 @@ row_undo_mod_upd_exist_sec(
 	heap = mem_heap_create(1024);
 
 	while (node->index != NULL) {
+		/* Skip all corrupted secondary index */
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		index = node->index;
 
 		if (row_upd_changes_ord_field_binary(node->index, node->update,
@@ -859,6 +881,9 @@ row_undo_mod(
 	node->index = dict_table_get_next_index(
 		dict_table_get_first_index(node->table));
 
+	/* Skip all corrupted secondary index */
+	dict_table_skip_corrupt_index(node->index);
+
 	if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
 
 		err = row_undo_mod_upd_exist_sec(node, thr);

=== modified file 'storage/innobase/row/row0upd.c'
--- a/storage/innobase/row/row0upd.c	2011-06-16 09:07:49 +0000
+++ b/storage/innobase/row/row0upd.c	2011-08-17 01:07:59 +0000
@@ -2320,6 +2320,13 @@ row_upd(
 
 	while (node->index != NULL) {
 
+		/* Skip corrupted index */
+		dict_table_skip_corrupt_index(node->index);
+
+		if (!node->index) {
+			break;
+		}
+
 		log_free_check();
 		err = row_upd_sec_step(node, thr);
 

=== modified file 'storage/innobase/sync/sync0sync.c'
--- a/storage/innobase/sync/sync0sync.c	2011-06-16 09:07:49 +0000
+++ b/storage/innobase/sync/sync0sync.c	2011-08-15 09:18:34 +0000
@@ -1232,6 +1232,7 @@ sync_thread_add_level(
 	case SYNC_DICT_HEADER:
 	case SYNC_TRX_I_S_RWLOCK:
 	case SYNC_TRX_I_S_LAST_READ:
+	case SYNC_IBUF_MUTEX:
 		if (!sync_thread_levels_g(array, level, TRUE)) {
 			fprintf(stderr,
 				"InnoDB: sync_thread_levels_g(array, %lu)"
@@ -1317,22 +1318,28 @@ sync_thread_add_level(
 		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
 		break;
 	case SYNC_TREE_NODE_NEW:
-		ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
-		     || sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+		ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE));
 		break;
 	case SYNC_INDEX_TREE:
-		if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
-		    && sync_thread_levels_contain(array, SYNC_FSP)) {
-			ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1,
-						  TRUE));
+		ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
+		break;
+	case SYNC_IBUF_TREE_NODE:
+		ut_a(sync_thread_levels_contain(array, SYNC_IBUF_INDEX_TREE)
+		     || sync_thread_levels_g(array, SYNC_IBUF_TREE_NODE - 1,
+					     TRUE));
+		break;
+	case SYNC_IBUF_TREE_NODE_NEW:
+		ut_a(sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+		break;
+	case SYNC_IBUF_INDEX_TREE:
+		if (sync_thread_levels_contain(array, SYNC_FSP)) {
+			ut_a(sync_thread_levels_g(
+				     array, SYNC_FSP_PAGE - 1, TRUE));
 		} else {
-			ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
-						  TRUE));
+			ut_a(sync_thread_levels_g(
+				     array, SYNC_IBUF_TREE_NODE - 1, TRUE));
 		}
 		break;
-	case SYNC_IBUF_MUTEX:
-		ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
-		break;
 	case SYNC_IBUF_PESS_INSERT_MUTEX:
 		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
 		ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));

=== modified file 'storage/innobase/ut/ut0ut.c'
--- a/storage/innobase/ut/ut0ut.c	2011-06-28 12:28:21 +0000
+++ b/storage/innobase/ut/ut0ut.c	2011-08-17 01:07:59 +0000
@@ -712,6 +712,8 @@ ut_strerr(
 		return("No index on referencing keys in referencing table");
 	case DB_PARENT_NO_INDEX:
 		return("No index on referenced keys in referenced table");
+	case DB_INDEX_CORRUPT:
+		return("Index corrupted");
 	case DB_END_OF_INDEX:
 		return("End of index");
 	/* do not add default: in order to produce a warning if new code

=== modified file 'support-files/mysql.spec.sh'
--- a/support-files/mysql.spec.sh	2011-07-22 08:34:45 +0000
+++ b/support-files/mysql.spec.sh	2011-08-10 18:39:49 +0000
@@ -127,13 +127,13 @@
       %define distro_description        Oracle Enterprise Linux 4
       %define distro_releasetag         oel4
       %define distro_buildreq           gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
-      %define distro_requires           chkconfig coreutils grep procps shadow-utils
+      %define distro_requires           chkconfig coreutils grep procps shadow-utils net-tools
     %else
       %if "%oelver" == "5"
         %define distro_description      Oracle Enterprise Linux 5
         %define distro_releasetag       oel5
         %define distro_buildreq         gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
-        %define distro_requires         chkconfig coreutils grep procps shadow-utils
+        %define distro_requires         chkconfig coreutils grep procps shadow-utils net-tools
       %else
         %{error:Oracle Enterprise Linux %{oelver} is unsupported}
       %endif
@@ -145,13 +145,13 @@
         %define distro_description      Red Hat Enterprise Linux 4
         %define distro_releasetag       rhel4
         %define distro_buildreq         gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
-        %define distro_requires         chkconfig coreutils grep procps shadow-utils
+        %define distro_requires         chkconfig coreutils grep procps shadow-utils net-tools
       %else
         %if "%rhelver" == "5"
           %define distro_description    Red Hat Enterprise Linux 5
           %define distro_releasetag     rhel5
           %define distro_buildreq       gcc-c++ gperf ncurses-devel perl readline-devel time zlib-devel
-          %define distro_requires       chkconfig coreutils grep procps shadow-utils
+          %define distro_requires       chkconfig coreutils grep procps shadow-utils net-tools
         %else
           %{error:Red Hat Enterprise Linux %{rhelver} is unsupported}
         %endif
@@ -1000,6 +1000,7 @@ echo "====="                            
 %attr(755, root, root) %{_bindir}/mysql_setpermission
 %attr(755, root, root) %{_bindir}/mysql_tzinfo_to_sql
 %attr(755, root, root) %{_bindir}/mysql_upgrade
+%attr(755, root, root) %{_bindir}/mysql_plugin
 %attr(755, root, root) %{_bindir}/mysql_zap
 %attr(755, root, root) %{_bindir}/mysqlbug
 %attr(755, root, root) %{_bindir}/mysqld_multi
@@ -1017,6 +1018,7 @@ echo "====="                            
 %attr(755, root, root) %{_sbindir}/rcmysql
 %attr(755, root, root) %{_libdir}/mysql/plugin/adt_null.so
 %attr(755, root, root) %{_libdir}/mysql/plugin/libdaemon_example.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/daemon_example.ini
 %attr(755, root, root) %{_libdir}/mysql/plugin/mypluglib.so
 %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so
 %attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so
@@ -1131,6 +1133,10 @@ echo "====="                            
 # merging BK trees)
 ##############################################################################
 %changelog
+* Mon Jul 25 2011 Chuck Bell <chuck.bell@stripped>
+
+- Added the mysql_plugin client - enables or disables plugins.
+
 * Thu Jul 21 2011 Sunanda Menon <sunanda.menon@stripped>
 
 - Fix bug#12561297: Added the MySQL embedded binary

=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c	2011-07-07 11:22:43 +0000
+++ b/tests/mysql_client_test.c	2011-08-03 13:53:44 +0000
@@ -19660,6 +19660,34 @@ static void test_bug12337762()
   DBUG_VOID_RETURN;
 }
 
+
+/*
+  BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
+*/
+
+static void test_bug11754979()
+{
+  MYSQL* conn;
+  DBUG_ENTER("test_bug11754979");
+
+  myheader("test_bug11754979");
+  DIE_UNLESS((conn= mysql_client_init(NULL)));
+  DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
+             opt_password, opt_db ? opt_db:"test", opt_port,
+             opt_unix_socket,  CLIENT_FOUND_ROWS));
+  myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
+  myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
+  myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
+  myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
+                            "ON DUPLICATE KEY UPDATE id = 4"));
+  DIE_UNLESS(mysql_affected_rows(conn) == 2);
+  myquery(mysql_query(conn, "DROP TABLE t1"));
+  mysql_close(conn);
+
+  DBUG_VOID_RETURN;
+}
+
+
 /*
   Read and parse arguments and MySQL options from my.cnf
 */
@@ -20005,6 +20033,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug56976", test_bug56976 },
   { "test_bug11766854", test_bug11766854 },
   { "test_bug12337762", test_bug12337762 },
+  { "test_bug11754979", test_bug11754979 },
   { 0, 0 }
 };
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5 branch (joerg.bruehe:3481 to 3499) Joerg Bruehe22 Aug