merge from 5.5 main
This commit is contained in:
commit
07366f2404
@ -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)
|
||||
|
18
mysql-test/suite/innodb/r/innodb_bug59733.result
Normal file
18
mysql-test/suite/innodb/r/innodb_bug59733.result
Normal file
@ -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;
|
81
mysql-test/suite/innodb/r/innodb_corrupt_bit.result
Normal file
81
mysql-test/suite/innodb/r/innodb_corrupt_bit.result
Normal file
@ -0,0 +1,81 @@
|
||||
set names utf8;
|
||||
CREATE TABLE corrupt_bit_test_ā(
|
||||
a INT AUTO_INCREMENT PRIMARY KEY,
|
||||
b CHAR(100),
|
||||
c INT,
|
||||
z INT,
|
||||
INDEX(b))
|
||||
ENGINE=InnoDB;
|
||||
INSERT INTO corrupt_bit_test_ā VALUES(0,'x',1, 1);
|
||||
CREATE UNIQUE INDEX idxā ON corrupt_bit_test_ā(c, b);
|
||||
CREATE UNIQUE INDEX idxē ON corrupt_bit_test_ā(z, b);
|
||||
SELECT * FROM corrupt_bit_test_ā;
|
||||
a b c z
|
||||
1 x 1 1
|
||||
select @@unique_checks;
|
||||
@@unique_checks
|
||||
0
|
||||
select @@innodb_change_buffering_debug;
|
||||
@@innodb_change_buffering_debug
|
||||
1
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+400,z+400 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+800,z+800 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1600,z+1600 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+4000,z+4000 FROM corrupt_bit_test_ā;
|
||||
select count(*) from corrupt_bit_test_ā;
|
||||
count(*)
|
||||
1024
|
||||
CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c);
|
||||
INSERT INTO corrupt_bit_test_ā VALUES(13000,'x',1,1);
|
||||
CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z);
|
||||
check table corrupt_bit_test_ā;
|
||||
Table Op Msg_type Msg_text
|
||||
test.corrupt_bit_test_ā check Warning InnoDB: The B-tree of index "idxā" is corrupted.
|
||||
test.corrupt_bit_test_ā check Warning InnoDB: The B-tree of index "idxē" is corrupted.
|
||||
test.corrupt_bit_test_ā 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_ā'; try to repair it
|
||||
show warnings;
|
||||
Level Code Message
|
||||
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_ā'; try to repair it
|
||||
insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
|
||||
select * from corrupt_bit_test_ā use index(primary) where a = 10001;
|
||||
a b c z
|
||||
10001 a 20001 20001
|
||||
begin;
|
||||
insert into corrupt_bit_test_ā values (10002, "a", 20002, 20002);
|
||||
delete from corrupt_bit_test_ā where a = 10001;
|
||||
insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001);
|
||||
rollback;
|
||||
drop index idxā on corrupt_bit_test_ā;
|
||||
check table corrupt_bit_test_ā;
|
||||
Table Op Msg_type Msg_text
|
||||
test.corrupt_bit_test_ā check Warning InnoDB: Index "idxē" is marked as corrupted
|
||||
test.corrupt_bit_test_ā check error Corrupt
|
||||
set names utf8;
|
||||
select z from corrupt_bit_test_ā;
|
||||
ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it
|
||||
drop index idxē on corrupt_bit_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;
|
53
mysql-test/suite/innodb/t/innodb_bug59733.test
Normal file
53
mysql-test/suite/innodb/t/innodb_bug59733.test
Normal file
@ -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;
|
120
mysql-test/suite/innodb/t/innodb_corrupt_bit.test
Normal file
120
mysql-test/suite/innodb/t/innodb_corrupt_bit.test
Normal file
@ -0,0 +1,120 @@
|
||||
#
|
||||
# Test for persistent corrupt bit for corrupted index and table
|
||||
#
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
# This test needs debug server
|
||||
--source include/have_debug.inc
|
||||
|
||||
-- disable_query_log
|
||||
# This test setup is extracted from bug56680.test:
|
||||
# The flag innodb_change_buffering_debug is only available in debug builds.
|
||||
# It instructs InnoDB to try to evict pages from the buffer pool when
|
||||
# change buffering is possible, so that the change buffer will be used
|
||||
# whenever possible.
|
||||
-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
|
||||
SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug;
|
||||
-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
|
||||
SET GLOBAL innodb_change_buffering_debug = 1;
|
||||
|
||||
# Turn off Unique Check to create corrupted index with dup key
|
||||
SET UNIQUE_CHECKS=0;
|
||||
|
||||
-- enable_query_log
|
||||
|
||||
set names utf8;
|
||||
|
||||
CREATE TABLE corrupt_bit_test_ā(
|
||||
a INT AUTO_INCREMENT PRIMARY KEY,
|
||||
b CHAR(100),
|
||||
c INT,
|
||||
z INT,
|
||||
INDEX(b))
|
||||
ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO corrupt_bit_test_ā VALUES(0,'x',1, 1);
|
||||
|
||||
# This is the first unique index we intend to corrupt
|
||||
CREATE UNIQUE INDEX idxā ON corrupt_bit_test_ā(c, b);
|
||||
|
||||
# This is the second unique index we intend to corrupt
|
||||
CREATE UNIQUE INDEX idxē ON corrupt_bit_test_ā(z, b);
|
||||
|
||||
SELECT * FROM corrupt_bit_test_ā;
|
||||
|
||||
select @@unique_checks;
|
||||
select @@innodb_change_buffering_debug;
|
||||
|
||||
# Create enough rows for the table, so that the insert buffer will be
|
||||
# used for modifying the secondary index page. There must be multiple
|
||||
# index pages, because changes to the root page are never buffered.
|
||||
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_ā;
|
||||
INSERT INTO corrupt_bit_test_ā 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;
|
@ -11,7 +11,5 @@ There should be *no* long test name listed below:
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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'
|
92
mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result
Normal file
92
mysql-test/suite/sys_vars/r/innodb_large_prefix_basic.result
Normal file
@ -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
|
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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_table);
|
||||
# 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_table);
|
||||
|
||||
--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;
|
||||
|
@ -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'
|
||||
|
||||
|
@ -54,5 +54,9 @@ select * from information_schema.global_variables where variable_name='innodb_io
|
||||
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;
|
||||
|
70
mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test
Normal file
70
mysql-test/suite/sys_vars/t/innodb_large_prefix_basic.test
Normal file
@ -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;
|
@ -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_timeout);
|
||||
# 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_timeout);
|
||||
|
||||
--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;
|
||||
|
@ -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 #
|
||||
|
@ -81,7 +81,8 @@ static const char *handler_error_messages[]=
|
||||
"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);
|
||||
|
@ -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 errflag)
|
||||
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.
|
||||
|
@ -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"
|
||||
|
@ -655,8 +655,8 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
||||
|
@ -3473,6 +3473,53 @@ buf_page_create(
|
||||
return(block);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
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. */
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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_compact;
|
||||
#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 */
|
||||
|
@ -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);
|
||||
|
@ -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, innobase_large_prefix,
|
||||
"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_system_variables[]= {
|
||||
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
|
||||
|
@ -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,
|
||||
|
@ -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) \
|
||||
btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,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.
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,21 +1318,27 @@ 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));
|
||||
} else {
|
||||
ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
|
||||
TRUE));
|
||||
}
|
||||
ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
|
||||
break;
|
||||
case SYNC_IBUF_MUTEX:
|
||||
ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
|
||||
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_IBUF_TREE_NODE - 1, TRUE));
|
||||
}
|
||||
break;
|
||||
case SYNC_IBUF_PESS_INSERT_MUTEX:
|
||||
ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
|
||||
|
@ -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
|
||||
|
@ -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 "=====" >> $STATUS_HISTORY
|
||||
# merging BK trees)
|
||||
##############################################################################
|
||||
%changelog
|
||||
* Fri Aug 19 2011 Joerg Bruehe <joerg.bruehe@oracle.com>
|
||||
|
||||
- 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@oracle.com>
|
||||
|
||||
- Added the mysql_plugin client - enables or disables plugins.
|
||||
|
Loading…
x
Reference in New Issue
Block a user