List:Commits« Previous MessageNext Message »
From:Bjorn Munch Date:August 22 2011 1:29pm
Subject:bzr push into mysql-5.5-mtr branch (bjorn.munch:3234 to 3239) Bug#12793170
View as plain text  
 3239 Bjorn Munch	2011-08-22
      Bug #12793170 MYSQLTEST: PROVIDE ACCESS TO ERROR NAMES THROUGH NUMERIC
      CODES AND VICE VERSA
        Followup: Some statement may give errors not in the list,
        map these to "<Unknown>" rather than failing.

    modified:
      client/mysqltest.cc
 3238 Bjorn Munch	2011-08-22 [merge]
      upmerge 11766654

    modified:
      mysql-test/include/mtr_check.sql
 3237 Bjorn Munch	2011-08-22
      Bug #12793170 MYSQLTEST: PROVIDE ACCESS TO ERROR NAMES THROUGH NUMERIC CODES AND VICE VERSA
        Added a second internal variable $mysql_errname
        This is set the same way as $mysql_errno
        Can be used like "if ($mysql_errname == ER_NO_SUCH_TABLE)...."

    modified:
      client/mysqltest.cc
      mysql-test/r/execution_constants.result
      mysql-test/r/mysqltest.result
      mysql-test/t/execution_constants.test
      mysql-test/t/mysqltest.test
 3236 Bjorn Munch	2011-08-22 [merge]
      merge from 5.5 main

    added:
      mysql-test/suite/innodb/r/innodb_bug59733.result
      mysql-test/suite/innodb/r/innodb_corrupt_bit.result
      mysql-test/suite/innodb/t/innodb_bug59733.test
      mysql-test/suite/innodb/t/innodb_corrupt_bit.test
      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:
      include/my_base.h
      mysql-test/suite/sys_vars/r/all_vars.result
      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
      mysys/my_handler_errors.h
      sql/handler.cc
      sql/share/errmsg-utf8.txt
      sql/sql_class.cc
      storage/innobase/btr/btr0btr.c
      storage/innobase/btr/btr0cur.c
      storage/innobase/btr/btr0pcur.c
      storage/innobase/btr/btr0sea.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/buf/buf0lru.c
      storage/innobase/dict/dict0crea.c
      storage/innobase/dict/dict0dict.c
      storage/innobase/dict/dict0load.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/ibuf/ibuf0ibuf.c
      storage/innobase/include/btr0btr.h
      storage/innobase/include/btr0btr.ic
      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/include/sync0sync.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/sync/sync0sync.c
      storage/innobase/ut/ut0ut.c
      support-files/mysql.spec.sh
 3235 Bjorn Munch	2011-08-16
      Bug #11759877 52223: TEST "PLUGIN_DIR_BASIC" DOES NOT SUPPORT RPM BUILD (TEST) DIRECTORY STRUC
      
        Undo previous fix, it is not reliable
        Drop setting $MYSQL_LIBDIR, mtr can't be sure anyway
        Test is set to override plugin-dir to some known existing dir

    added:
      mysql-test/suite/sys_vars/t/plugin_dir_basic-master.opt
    modified:
      mysql-test/include/mysqld--help.inc
      mysql-test/mysql-test-run.pl
      mysql-test/suite/sys_vars/r/plugin_dir_basic.result
      mysql-test/suite/sys_vars/t/plugin_dir_basic.test
 3234 Bjorn Munch	2011-08-12 [merge]
      merge from 5.5 main

    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:
      VERSION
      client/CMakeLists.txt
      include/my_global.h
      mysql-test/collections/default.experimental
      mysql-test/include/plugin.defs
      mysql-test/mysql-test-run.pl
      mysql-test/r/func_time.result
      mysql-test/r/information_schema.result
      mysql-test/r/merge.result
      mysql-test/r/sp.result
      mysql-test/r/sp_trans.result
      mysql-test/suite/innodb/r/innodb-zip.result
      mysql-test/suite/innodb/t/innodb-zip.test
      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
      mysql-test/t/func_time.test
      mysql-test/t/information_schema.test
      mysql-test/t/merge.test
      mysql-test/t/sp.test
      mysql-test/t/sp_trans.test
      plugin/daemon_example/CMakeLists.txt
      sql/item_timefunc.cc
      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_parse.cc
      sql/sql_prepare.cc
      sql/sql_select.cc
      sql/sql_show.cc
      sql/sql_yacc.yy
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/row/row0sel.c
      storage/myisammrg/ha_myisammrg.cc
      storage/myisammrg/myrg_open.c
      support-files/mysql.spec.sh
      tests/mysql_client_test.c
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2011-07-22 07:50:44 +0000
+++ b/client/mysqltest.cc	2011-08-22 12:42:12 +0000
@@ -494,6 +494,7 @@ void str_to_file(const char *fname, char
 void str_to_file2(const char *fname, char *str, int size, my_bool append);
 
 void fix_win_paths(const char *val, int len);
+const char *get_errname_from_code (uint error_code);
 
 #ifdef __WIN__
 void free_tmp_sh_file();
@@ -2263,6 +2264,7 @@ void var_set_int(const char* name, int v
 void var_set_errno(int sql_errno)
 {
   var_set_int("$mysql_errno", sql_errno);
+  var_set_string("$mysql_errname", get_errname_from_code(sql_errno));
 }
 
 
@@ -4670,8 +4672,7 @@ void do_shutdown_server(struct st_comman
 }
 
 
-#if MYSQL_VERSION_ID >= 50000
-/* List of error names to error codes, available from 5.0 */
+/* List of error names to error codes */
 typedef struct
 {
   const char *name;
@@ -4681,6 +4682,7 @@ typedef struct
 
 static st_error global_error_names[] =
 {
+  { "<No error>", -1, "" },
 #include <mysqld_ername.h>
   { 0, 0, 0 }
 };
@@ -4711,16 +4713,28 @@ uint get_errcode_from_name(char *error_n
     die("Unknown SQL error name '%s'", error_name);
   DBUG_RETURN(0);
 }
-#else
-uint get_errcode_from_name(char *error_name __attribute__((unused)),
-                           char *error_end __attribute__((unused)))
+
+const char *get_errname_from_code (uint error_code)
 {
-  abort_not_in_this_version();
-  return 0; /* Never reached */
-}
-#endif
+   st_error *e= global_error_names;
 
+   DBUG_ENTER("get_errname_from_code");
+   DBUG_PRINT("enter", ("error_code: %d", error_code));
 
+   if (! error_code)
+   {
+     DBUG_RETURN("");
+   }
+   for (; e->name; e++)
+   {
+     if (e->code == error_code)
+     {
+       DBUG_RETURN(e->name);
+     }
+   }
+   /* Apparently, errors without known names may occur */
+   DBUG_RETURN("<Unknown>");
+} 
 
 void do_get_errcodes(struct st_command *command)
 {

=== 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 'mysql-test/include/mtr_check.sql'
--- a/mysql-test/include/mtr_check.sql	2011-07-04 07:33:16 +0000
+++ b/mysql-test/include/mtr_check.sql	2011-08-17 12:42:18 +0000
@@ -72,3 +72,13 @@ BEGIN
     mysql.user;
 
 END||
+
+--
+-- Procedure used by test case used to force all
+-- servers to restart after testcase and thus skipping
+-- check test case after test
+--
+CREATE DEFINER=root@localhost PROCEDURE force_restart()
+BEGIN
+  SELECT 1 INTO OUTFILE 'force_restart';
+END||

=== modified file 'mysql-test/include/mysqld--help.inc'
--- a/mysql-test/include/mysqld--help.inc	2010-09-30 13:52:39 +0000
+++ b/mysql-test/include/mysqld--help.inc	2011-08-16 09:08:10 +0000
@@ -26,7 +26,7 @@ perl;
 
   # And substitute the content some environment variables with their
   # names:
-  @env=qw/MYSQLTEST_VARDIR MYSQL_TEST_DIR MYSQL_LIBDIR MYSQL_CHARSETSDIR MYSQL_SHAREDIR/;
+  @env=qw/MYSQLTEST_VARDIR MYSQL_TEST_DIR MYSQL_CHARSETSDIR MYSQL_SHAREDIR/;
 
   $re1=join('|', @skipvars, @plugins);
   $re2=join('|', @plugins);

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2011-07-19 14:17:58 +0000
+++ b/mysql-test/mysql-test-run.pl	2011-08-16 09:08:10 +0000
@@ -2295,12 +2295,6 @@ sub environment_setup {
   $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'port'};
   $ENV{'MYSQL_TMP_DIR'}=      $opt_tmpdir;
   $ENV{'MYSQLTEST_VARDIR'}=   $opt_vardir;
-  # Used for guessing default plugin dir, we can't really know for sure
-  $ENV{'MYSQL_LIBDIR'}=       "$basedir/lib";
-  # Override if this does not exist, but lib64 does (best effort)
-  if (! -d "$basedir/lib" && -d "$basedir/lib64") {
-    $ENV{'MYSQL_LIBDIR'}=     "$basedir/lib64";
-  }
   $ENV{'MYSQL_BINDIR'}=       "$bindir";
   $ENV{'MYSQL_SHAREDIR'}=     $path_language;
   $ENV{'MYSQL_CHARSETSDIR'}=  $path_charsetsdir;

=== modified file 'mysql-test/r/execution_constants.result'
--- a/mysql-test/r/execution_constants.result	2006-09-27 18:42:56 +0000
+++ b/mysql-test/r/execution_constants.result	2011-08-22 11:58:49 +0000
@@ -7,6 +7,6 @@ PRIMARY KEY  (`ID_MEMBER`,`ID_BOARD`),
 KEY `logTime` (`logTime`)
 ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;
 INSERT INTO `t_bug21476` VALUES (2,2,1154870939,0),(1,2,1154870957,0),(2,183,1154941362,0),(2,84,1154904301,0),(1,84,1154905867,0),(2,13,1154947484,10271),(3,84,1154880549,0),(1,6,1154892183,0),(2,25,1154947581,10271),(3,25,1154904760,0),(1,25,1154947373,10271),(1,179,1154899992,0),(2,179,1154899410,0),(5,25,1154901666,0),(2,329,1154902026,0),(3,329,1154902040,0),(1,329,1154902058,0),(1,13,1154930841,0),(3,85,1154904987,0),(1,183,1154929665,0),(3,13,1154931268,0),(1,85,1154936888,0),(1,169,1154937959,0),(2,169,1154941717,0),(3,183,1154939810,0),(3,169,1154941734,0);
-Assertion: mysql_errno 1436 == 1436
+Assertion: mysql_errname ER_STACK_OVERRUN_NEED_MORE == ER_STACK_OVERRUN_NEED_MORE
 DROP TABLE `t_bug21476`;
 End of 5.0 tests.

=== modified file 'mysql-test/r/mysqltest.result'
--- a/mysql-test/r/mysqltest.result	2011-01-11 14:15:25 +0000
+++ b/mysql-test/r/mysqltest.result	2011-08-22 11:58:49 +0000
@@ -1,6 +1,5 @@
-select 0 as "before_use_test" ;
-before_use_test
-0
+-1 before test
+<No error> before test
 select otto from (select 1 as otto) as t1;
 otto
 1
@@ -21,27 +20,32 @@ mysqltest: At line 1: query 'select frie
 select otto from (select 1 as otto) as t1;
 otto
 1
+
 select 0 as "after_successful_stmt_errno" ;
 after_successful_stmt_errno
 0
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+ER_PARSE_ERROR
 select 1064 as "after_wrong_syntax_errno" ;
 after_wrong_syntax_errno
 1064
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+ER_PARSE_ERROR
 select 1064 as "after_let_var_equal_value" ;
 after_let_var_equal_value
 1064
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 set @my_var= 'abc' ;
+
 select 0 as "after_set_var_equal_value" ;
 after_set_var_equal_value
 0
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+ER_PARSE_ERROR
 select 1064 as "after_disable_warnings_command" ;
 after_disable_warnings_command
 1064
@@ -49,6 +53,7 @@ drop table if exists t1 ;
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 drop table if exists t1 ;
+
 select 0 as "after_disable_warnings" ;
 after_disable_warnings
 0
@@ -56,6 +61,7 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 select 3 from t1 ;
 ERROR 42S02: Table 'test.t1' doesn't exist
+ER_NO_SUCH_TABLE
 select 1146 as "after_minus_masked" ;
 after_minus_masked
 1146
@@ -63,6 +69,7 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 select 3 from t1 ;
 ERROR 42S02: Table 'test.t1' doesn't exist
+ER_NO_SUCH_TABLE
 select 1146 as "after_!_masked" ;
 after_!_masked
 1146
@@ -75,6 +82,7 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 prepare stmt from "select 3 from t1" ;
 ERROR 42S02: Table 'test.t1' doesn't exist
+ER_NO_SUCH_TABLE
 select 1146 as "after_failing_prepare" ;
 after_failing_prepare
 1146
@@ -82,6 +90,7 @@ create table t1 ( f1 char(10));
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 prepare stmt from "select 3 from t1" ;
+
 select 0 as "after_successful_prepare" ;
 after_successful_prepare
 0
@@ -89,6 +98,7 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 execute stmt;
 3
+
 select 0 as "after_successful_execute" ;
 after_successful_execute
 0
@@ -97,6 +107,7 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 execute stmt;
 ERROR 42S02: Table 'test.t1' doesn't exist
+ER_NO_SUCH_TABLE
 select 1146 as "after_failing_execute" ;
 after_failing_execute
 1146
@@ -104,12 +115,14 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 execute __stmt_;
 ERROR HY000: Unknown prepared statement handler (__stmt_) given to EXECUTE
+ER_UNKNOWN_STMT_HANDLER
 select 1243 as "after_failing_execute" ;
 after_failing_execute
 1243
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 deallocate prepare stmt;
+
 select 0 as "after_successful_deallocate" ;
 after_successful_deallocate
 0
@@ -117,11 +130,13 @@ garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
 deallocate prepare __stmt_;
 ERROR HY000: Unknown prepared statement handler (__stmt_) given to DEALLOCATE PREPARE
+ER_UNKNOWN_STMT_HANDLER
 select 1243 as "after_failing_deallocate" ;
 after_failing_deallocate
 1243
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+ER_PARSE_ERROR
 select 1064 as "after_--disable_abort_on_error" ;
 after_--disable_abort_on_error
 1064
@@ -131,12 +146,14 @@ select 3 from t1 ;
 ERROR 42S02: Table 'test.t1' doesn't exist
 select 3 from t1 ;
 ERROR 42S02: Table 'test.t1' doesn't exist
+ER_NO_SUCH_TABLE
 select 1146 as "after_!errno_masked_error" ;
 after_!errno_masked_error
 1146
 mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1000...
 garbage ;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+ER_PARSE_ERROR
 select 1064 as "after_--enable_abort_on_error" ;
 after_--enable_abort_on_error
 1064

=== 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 09:39:55 +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�t_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_�ERT 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 "idxWarning	InnoDB: The B-tree of index "idx��" is corrupted.
+test.corrupt_bit_test_��	check	error	Corrupt
+select c from 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_ge
+Warning	179	InnoDB: Index "idx��" for table "test"."corrupt_bit_test_��" is marked as corrupted
+Error	1034	Incorrect key file for table 'corrupt_bit_test_�pt_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_�_test_��;
+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;

=== 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�nd 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_�� 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_��;
+
+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-08-08 11:31:09 +0000
+++ b/mysql-test/suite/sys_vars/r/all_vars.result	2011-08-17 03:51:40 +0000
@@ -11,7 +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_LARGE_PREFIX
-INNODB_LARGE_PREFIX
 drop table t1;
 drop table t2;

=== 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

=== modified file 'mysql-test/suite/sys_vars/r/plugin_dir_basic.result'
--- a/mysql-test/suite/sys_vars/r/plugin_dir_basic.result	2009-12-22 09:35:56 +0000
+++ b/mysql-test/suite/sys_vars/r/plugin_dir_basic.result	2011-08-16 09:08:10 +0000
@@ -1,20 +1,20 @@
 select @@global.plugin_dir;
 @@global.plugin_dir
-MYSQL_LIBDIR/plugin
+MYSQL_TMP_DIR
 select @@session.plugin_dir;
 ERROR HY000: Variable 'plugin_dir' is a GLOBAL variable
 show global variables like 'plugin_dir';
 Variable_name	Value
-plugin_dir	MYSQL_LIBDIR/plugin
+plugin_dir	MYSQL_TMP_DIR
 show session variables like 'plugin_dir';
 Variable_name	Value
-plugin_dir	MYSQL_LIBDIR/plugin
+plugin_dir	MYSQL_TMP_DIR
 select * from information_schema.global_variables where variable_name='plugin_dir';
 VARIABLE_NAME	VARIABLE_VALUE
-PLUGIN_DIR	MYSQL_LIBDIR/plugin
+PLUGIN_DIR	MYSQL_TMP_DIR
 select * from information_schema.session_variables where variable_name='plugin_dir';
 VARIABLE_NAME	VARIABLE_VALUE
-PLUGIN_DIR	MYSQL_LIBDIR/plugin
+PLUGIN_DIR	MYSQL_TMP_DIR
 set global plugin_dir=1;
 ERROR HY000: Variable 'plugin_dir' is a read only variable
 set session plugin_dir=1;

=== 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_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/plugin_dir_basic-master.opt'
--- a/mysql-test/suite/sys_vars/t/plugin_dir_basic-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/plugin_dir_basic-master.opt	2011-08-16 09:08:10 +0000
@@ -0,0 +1 @@
+--plugin-dir=$MYSQL_TMP_DIR

=== modified file 'mysql-test/suite/sys_vars/t/plugin_dir_basic.test'
--- a/mysql-test/suite/sys_vars/t/plugin_dir_basic.test	2009-12-22 09:35:56 +0000
+++ b/mysql-test/suite/sys_vars/t/plugin_dir_basic.test	2011-08-16 09:08:10 +0000
@@ -3,20 +3,20 @@
 #
 
 #
-# on windows it's <basedir>/lib/plugin
-# on unix it's <basedir>/lib/mysql/plugin
+# Don't rely on being able to guess the correct default.
+# -master.opt file for this test sets plugin_dir to a known directory
 #
---replace_result $MYSQL_LIBDIR MYSQL_LIBDIR /mysql/ /
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR /mysql/ /
 select @@global.plugin_dir;
 --error ER_INCORRECT_GLOBAL_LOCAL_VAR
 select @@session.plugin_dir;
---replace_result $MYSQL_LIBDIR MYSQL_LIBDIR /mysql/ /
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR /mysql/ /
 show global variables like 'plugin_dir';
---replace_result $MYSQL_LIBDIR MYSQL_LIBDIR /mysql/ /
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR /mysql/ /
 show session variables like 'plugin_dir';
---replace_result $MYSQL_LIBDIR MYSQL_LIBDIR /mysql/ /
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR /mysql/ /
 select * from information_schema.global_variables where variable_name='plugin_dir';
---replace_result $MYSQL_LIBDIR MYSQL_LIBDIR /mysql/ /
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR /mysql/ /
 select * from information_schema.session_variables where variable_name='plugin_dir';
 
 #

=== modified file 'mysql-test/t/execution_constants.test'
--- a/mysql-test/t/execution_constants.test	2010-11-17 10:16:13 +0000
+++ b/mysql-test/t/execution_constants.test	2011-08-22 11:58:49 +0000
@@ -38,7 +38,7 @@ while ($i)
 {
   # If we SEGV because the min stack size is exceeded, this would return error
   # 2013 .
-  error 0,1436 //
+  error 0,ER_STACK_OVERRUN_NEED_MORE //
   eval $query_head 0 $query_tail//
 
   if ($mysql_errno)
@@ -48,10 +48,10 @@ while ($i)
     # limit, we still have enough space reserved to report an error.
     let $i = 1//
 
-    # Check that mysql_errno is 1436
-    if ($mysql_errno != 1436)
+    # Check that mysql_errname is ER_STACK_OVERRUN_NEED_MORE
+    if ($mysql_errname != ER_STACK_OVERRUN_NEED_MORE)
     {
-      die Wrong error triggered, expected 1436 but got $mysql_errno//
+      die Wrong error triggered, expected ER_STACK_OVERRUN_NEED_MORE but got $mysql_errname//
     }
 
   }
@@ -76,7 +76,7 @@ while ($i)
 enable_result_log//
 enable_query_log//
 
-echo Assertion: mysql_errno 1436 == $mysql_errno//
+echo Assertion: mysql_errname ER_STACK_OVERRUN_NEED_MORE == $mysql_errname//
 
 delimiter ;//
 DROP TABLE `t_bug21476`;

=== modified file 'mysql-test/t/mysqltest.test'
--- a/mysql-test/t/mysqltest.test	2011-01-11 14:15:25 +0000
+++ b/mysql-test/t/mysqltest.test	2011-08-22 11:58:49 +0000
@@ -1,3 +1,14 @@
+# ----------------------------------------------------------------------------
+# $mysql_errno contains the return code of the last command
+# sent to the server.
+# ----------------------------------------------------------------------------
+# get $mysql_errno before the first statement
+#     $mysql_errno should be -1
+# get $mysql_errname as well
+
+echo $mysql_errno before test;
+echo $mysql_errname before test;
+
 -- source include/have_log_bin.inc
 
 # This test should work in embedded server after mysqltest is fixed
@@ -34,15 +45,6 @@
 # ============================================================================
 
 # ----------------------------------------------------------------------------
-# $mysql_errno contains the return code of the last command
-# sent to the server.
-# ----------------------------------------------------------------------------
-# get $mysql_errno before the first statement
-#     $mysql_errno should be -1
-eval select $mysql_errno as "before_use_test" ;
-
-
-# ----------------------------------------------------------------------------
 # Positive case(statement)
 # ----------------------------------------------------------------------------
 
@@ -134,6 +136,7 @@ select friedrich from (select 1 as otto)
 # check mysql_errno = 0 after successful statement
 # ----------------------------------------------------------------------------
 select otto from (select 1 as otto) as t1;
+echo $mysql_errname;
 eval select $mysql_errno as "after_successful_stmt_errno" ;
 
 #----------------------------------------------------------------------------
@@ -142,6 +145,7 @@ eval select $mysql_errno as "after_succe
 --error ER_PARSE_ERROR
 
 garbage ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_wrong_syntax_errno" ;
 
 # ----------------------------------------------------------------------------
@@ -151,6 +155,7 @@ eval select $mysql_errno as "after_wrong
 
 garbage ;
 let $my_var= 'abc' ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_let_var_equal_value" ;
 
 # ----------------------------------------------------------------------------
@@ -160,6 +165,7 @@ eval select $mysql_errno as "after_let_v
 
 garbage ;
 set @my_var= 'abc' ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_set_var_equal_value" ;
 
 # ----------------------------------------------------------------------------
@@ -170,6 +176,7 @@ eval select $mysql_errno as "after_set_v
 
 garbage ;
 --disable_warnings
+echo $mysql_errname;
 eval select $mysql_errno as "after_disable_warnings_command" ;
 
 # ----------------------------------------------------------------------------
@@ -182,6 +189,7 @@ drop table if exists t1 ;
 
 garbage ;
 drop table if exists t1 ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_disable_warnings" ;
 --enable_warnings
 
@@ -194,6 +202,7 @@ garbage ;
 --error ER_NO_SUCH_TABLE
 
 select 3 from t1 ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_minus_masked" ;
 --error ER_PARSE_ERROR
 
@@ -201,6 +210,7 @@ garbage ;
 --error ER_NO_SUCH_TABLE
 
 select 3 from t1 ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_!_masked" ;
 
 # ----------------------------------------------------------------------------
@@ -222,6 +232,7 @@ garbage ;
 --error ER_NO_SUCH_TABLE
 
 prepare stmt from "select 3 from t1" ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_failing_prepare" ;
 create table t1 ( f1 char(10));
 
@@ -230,6 +241,7 @@ create table t1 ( f1 char(10));
 
 garbage ;
 prepare stmt from "select 3 from t1" ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_successful_prepare" ;
 
 # successful execute
@@ -237,6 +249,7 @@ eval select $mysql_errno as "after_succe
 
 garbage ;
 execute stmt;
+echo $mysql_errname;
 eval select $mysql_errno as "after_successful_execute" ;
 
 # failing execute (table has been dropped)
@@ -247,6 +260,7 @@ garbage ;
 --error ER_NO_SUCH_TABLE
 
 execute stmt;
+echo $mysql_errname;
 eval select $mysql_errno as "after_failing_execute" ;
 
 # failing execute (unknown statement)
@@ -256,6 +270,7 @@ garbage ;
 --error ER_UNKNOWN_STMT_HANDLER
 
 execute __stmt_;
+echo $mysql_errname;
 eval select $mysql_errno as "after_failing_execute" ;
 
 # successful deallocate
@@ -263,6 +278,7 @@ eval select $mysql_errno as "after_faili
 
 garbage ;
 deallocate prepare stmt;
+echo $mysql_errname;
 eval select $mysql_errno as "after_successful_deallocate" ;
 
 # failing deallocate ( statement handle does not exist )
@@ -272,6 +288,7 @@ garbage ;
 --error ER_UNKNOWN_STMT_HANDLER
 
 deallocate prepare __stmt_;
+echo $mysql_errname;
 eval select $mysql_errno as "after_failing_deallocate" ;
 
 
@@ -299,6 +316,7 @@ eval select $mysql_errno as "after_faili
 
 garbage ;
 --disable_abort_on_error
+echo $mysql_errname;
 eval select $mysql_errno as "after_--disable_abort_on_error" ;
 
 # ----------------------------------------------------------------------------
@@ -316,6 +334,7 @@ select 3 from t1 ;
 --error ER_NO_SUCH_TABLE
 
 select 3 from t1 ;
+echo $mysql_errname;
 eval select $mysql_errno as "after_!errno_masked_error" ;
 # expected error <> response
 # --error 1000
@@ -341,6 +360,7 @@ EOF
 
 garbage ;
 --enable_abort_on_error
+echo $mysql_errname;
 eval select $mysql_errno as "after_--enable_abort_on_error" ;
 
 # ----------------------------------------------------------------------------

=== 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 '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_class.cc'
--- a/sql/sql_class.cc	2011-08-02 07:54:35 +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);
 

=== 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-08-08 09:16:15 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-08-17 09:39:55 +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,29 @@ 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);
+
+	ut_ad((ulint) (bufend - buf) < buflen);
+
+	buf[bufend - buf] = '\0';
+}
+
 /**********************************************************************//**
 Determines if the currently running transaction has been interrupted.
 @return	TRUE if interrupted */
@@ -5664,12 +5689,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 +5882,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 +7568,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;
@@ -8184,6 +8238,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());
@@ -8225,6 +8280,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 */
@@ -8233,6 +8296,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);
@@ -8241,11 +8305,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;
 		}
 
@@ -8258,11 +8327,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;
 		}
 
@@ -8276,12 +8360,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)) {
@@ -8308,6 +8399,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;
 
@@ -11101,6 +11206,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.",
@@ -11360,6 +11470,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,mtr) \
+#  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,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-08-10 09:58:22 +0000
+++ b/storage/innobase/row/row0sel.c	2011-08-17 01:07:59 +0000
@@ -3441,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-08-10 18:39:49 +0000
+++ b/support-files/mysql.spec.sh	2011-08-19 17:26:27 +0000
@@ -421,7 +421,7 @@ mkdir debug
   # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
   ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
            -DCMAKE_BUILD_TYPE=Debug \
-           -DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" \
+           -DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
            -DFEATURE_SET="%{feature_set}" \
            -DCOMPILATION_COMMENT="%{compilation_comment_debug}" \
            -DMYSQL_SERVER_SUFFIX="%{server_suffix}"
@@ -436,7 +436,7 @@ mkdir release
   # XXX: install_layout so we can't just set it based on INSTALL_LAYOUT=RPM
   ${CMAKE} ../%{src_dir} -DBUILD_CONFIG=mysql_release -DINSTALL_LAYOUT=RPM \
            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-           -DMYSQL_UNIX_ADDR="/var/lib/mysql/mysql.sock" \
+           -DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
            -DFEATURE_SET="%{feature_set}" \
            -DCOMPILATION_COMMENT="%{compilation_comment_release}" \
            -DMYSQL_SERVER_SUFFIX="%{server_suffix}"
@@ -1133,6 +1133,11 @@ echo "====="
 # merging BK trees)
 ##############################################################################
 %changelog
+* Fri Aug 19 2011 Joerg Bruehe <joerg.bruehe@stripped>
+
+- Null-upmerge the fix of bug#37165: This spec file is not affected.
+- Replace "/var/lib/mysql" by the spec file variable "%{mysqldatadir}".
+
 * Mon Jul 25 2011 Chuck Bell <chuck.bell@stripped>
 
 - Added the mysql_plugin client - enables or disables plugins.

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-mtr branch (bjorn.munch:3234 to 3239) Bug#12793170Bjorn Munch22 Aug