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#12793170 | Bjorn Munch | 22 Aug |