1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
# WL#7142 InnoDB: Simplify tablespace discovery during crash recovery
# Test the detection of duplicate tablespaces.
--source include/have_innodb.inc
--source include/no_valgrind_without_big.inc
# Embedded server does not support crashing
--source include/not_embedded.inc
call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile:");
FLUSH TABLES;
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB;
--source include/restart_mysqld.inc
--source include/no_checkpoint_start.inc
CREATE TABLE t3(a INT PRIMARY KEY) ENGINE=InnoDB;
BEGIN;
INSERT INTO t3 VALUES (33101),(347);
INSERT INTO t1 VALUES (42),(9),(101);
RENAME TABLE t1 TO t2;
UPDATE t2 SET a=347 where a=42;
COMMIT;
--let CLEANUP_IF_CHECKPOINT=DROP TABLE t2,t3;
--source include/no_checkpoint_end.inc
--echo # Fault 0 (no real fault): Orphan file with duplicate space_id.
--copy_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t0.ibd
--echo # Fault 1: Two dirty files with the same space_id.
--copy_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t1.ibd
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
# This could fail to refuse InnoDB startup, in case there was a log
# checkpoint after the INSERT. That is what we checked above.
--source include/start_mysqld.inc
eval $check_no_innodb;
let SEARCH_PATTERN= InnoDB: Ignoring data file '.*t2.ibd' with space ID \d+. Another data file called .*t1.ibd exists with the same space ID;
--source include/search_pattern_in_file.inc
--source include/shutdown_mysqld.inc
--remove_file $MYSQLD_DATADIR/test/t1.ibd
# This could fail to refuse InnoDB startup, in case there was a log
# checkpoint after the CREATE TABLE t3. That is what we checked above.
--echo # Fault 2: Wrong space_id in a dirty file, and a missing file.
--move_file $MYSQLD_DATADIR/test/t3.ibd $MYSQLD_DATADIR/test/t1.ibd
--source include/start_mysqld.inc
eval $check_no_innodb;
let SEARCH_PATTERN= InnoDB: Tablespace \d+ was not found at.*t3.ibd;
--source include/search_pattern_in_file.inc
--source include/shutdown_mysqld.inc
--move_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t3.ibd
--echo # Fault 3: Wrong space_id in a dirty file, and no missing file.
# Swap t2.ibd and t3.ibd.
--move_file $MYSQLD_DATADIR/test/t3.ibd $MYSQLD_DATADIR/test/t.ibd
--move_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t3.ibd
--move_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t2.ibd
--source include/start_mysqld.inc
eval $check_no_innodb;
let SEARCH_PATTERN= InnoDB: Ignoring data file '.*t[23].ibd' with space ID;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Tablespace \d+ was not found at .*t1.ibd;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Tablespace \d+ was not found at .*t3.ibd;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= InnoDB: Set innodb_force_recovery=1 to ignore this and to permanently lose all changes to the tablespace;
--source include/search_pattern_in_file.inc
--source include/shutdown_mysqld.inc
# Swap back t3.ibd, but hide t2.ibd (which the redo log also knows as t1.ibd).
--move_file $MYSQLD_DATADIR/test/t3.ibd $MYSQLD_DATADIR/test/t.ibd
--move_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t3.ibd
--echo # Fault 4: Missing data file
--source include/start_mysqld.inc
eval $check_no_innodb;
--source include/shutdown_mysqld.inc
let SEARCH_PATTERN= InnoDB: Tablespace \d+ was not found at .*t[12].ibd.
.*InnoDB: Set innodb_force_recovery=1 to ignore this and to permanently lose all changes to the tablespace;
--source include/search_pattern_in_file.inc
--echo # Fault 5: Wrong type of data file
--mkdir $MYSQLD_DATADIR/test/t2.ibd
--source include/start_mysqld.inc
eval $check_no_innodb;
--source include/shutdown_mysqld.inc
# On Linux, lseek() would typically report EINVAL when invoked on a directory.
# On other plaftorms as well as some GNU/Linux based environments, such as
# a Ubuntu 22.04 based image on Amazon Web Services,
# os_file_get_size() would succeed on a directory, and we would get another
# error about inability to apply log to a corrupted page.
#--let SEARCH_PATTERN= InnoDB: Could not measure the size of single-table tablespace file '.*test/t2\\.ibd'
#--source include/search_pattern_in_file.inc
--rmdir $MYSQLD_DATADIR/test/t2.ibd
# Create a short file.
--write_file $MYSQLD_DATADIR/test/t2.ibd
EOF
--source include/start_mysqld.inc
eval $check_no_innodb;
--source include/shutdown_mysqld.inc
let SEARCH_PATTERN= \[Note\] InnoDB: Cannot read first page of .*t2.ibd;
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN= .*\[ERROR\] InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=3\\] of corrupted file './test/t2\\.ibd';
--source include/search_pattern_in_file.inc
# Restore t2.ibd
--remove_file $MYSQLD_DATADIR/test/t2.ibd
--move_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t2.ibd
--source include/start_mysqld.inc
SELECT * FROM t2;
SELECT * FROM t3;
SHOW TABLES;
DROP TABLE t2,t3;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
--remove_file $MYSQLD_DATADIR/test/t0.ibd
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
DROP TABLE t0;
--disable_query_log
# The following are for the orphan file t0.ibd or for the directory t2.ibd:
call mtr.add_suppression("InnoDB: Operating system error number [0-9]* in a file operation");
call mtr.add_suppression("InnoDB: Error number \\d+ means");
call mtr.add_suppression("InnoDB: Cannot create file '.*t0.ibd'");
call mtr.add_suppression("InnoDB: The file '.*t0\.ibd' already exists");
call mtr.add_suppression("InnoDB: Cannot open datafile for read-write: '.*t2\.ibd'");
call mtr.add_suppression("InnoDB: Could not measure the size of single-table tablespace file '.*test/t2\\.ibd'");
# The following are for aborted startup without --innodb-force-recovery:
call mtr.add_suppression("InnoDB: Tablespace .* was not found at .*test");
call mtr.add_suppression("InnoDB: Cannot read first page of '.*test.[tu]2.ibd': I/O error");
call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=3\\] of corrupted file './test/t2\\.ibd'");
call mtr.add_suppression("InnoDB: Datafile '.*test.*ibd' is corrupted");
call mtr.add_suppression("InnoDB: Cannot replay file rename. Remove either file and try again");
call mtr.add_suppression("InnoDB: Cannot rename.*because the target file exists");
call mtr.add_suppression("InnoDB: Log scan aborted at LSN");
# The following are for the --innodb-force-recovery=1 with broken u* tables:
call mtr.add_suppression("InnoDB: The size of the file .*u[12]\\.ibd is only [1-9][0-9]* bytes, should be at least 65536");
call mtr.add_suppression("InnoDB: The size of tablespace file '.*test/u[12].ibd' is only");
call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified");
call mtr.add_suppression("InnoDB: .*you must create directories");
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*u[1-5]\.ibd'");
call mtr.add_suppression("InnoDB: Could not find a valid tablespace file for `test/u[1-5]`");
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/u[1-3] because it could not be opened\\.");
call mtr.add_suppression("InnoDB: Failed to find tablespace for table .* in the cache. Attempting to load the tablespace with space id");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
call mtr.add_suppression("Fewer engines are enabled now than were before the crash");
call mtr.add_suppression("Plugin 'InnoDB' \(init function returned error\|registration as a STORAGE ENGINE failed\)");
call mtr.add_suppression("InnoDB: Table test/u[123] in the InnoDB data dictionary has tablespace id [1-9][0-9]*, but tablespace with that id or name does not exist\\. Have you deleted or moved \\.ibd files\\?");
call mtr.add_suppression("InnoDB: Cannot replay rename of tablespace.*");
call mtr.add_suppression("InnoDB: Attempted to open a previously opened tablespace");
call mtr.add_suppression("InnoDB: Recovery cannot access file");
call mtr.add_suppression("InnoDB: Cannot read first page in datafile:");
FLUSH TABLES;
--enable_query_log
--source include/no_checkpoint_start.inc
CREATE TABLE u1(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE u2(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE u3(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE u4(a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO u4 VALUES(1);
RENAME TABLE u4 TO u5;
RENAME TABLE u5 TO u6;
INSERT INTO u6 VALUES(2);
--let CLEANUP_IF_CHECKPOINT=DROP TABLE u1,u2,u3,u6;
--source include/no_checkpoint_end.inc
--echo # Fault 6: All-zero data file and innodb_force_recovery
--remove_file $MYSQLD_DATADIR/test/u1.ibd
--remove_file $MYSQLD_DATADIR/test/u2.ibd
--remove_file $MYSQLD_DATADIR/test/u3.ibd
# InnoDB: Header page consists of zero bytes
--perl
die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/test/u1.ibd");
print FILE "\0" x 16384;
close(FILE);
EOF
--write_line "" $MYSQLD_DATADIR/test/u2.ibd
--copy_file $MYSQLD_DATADIR/test/u6.ibd $MYSQLD_DATADIR/test/u4.ibd
--let $restart_parameters= --innodb-force-recovery=1
--source include/start_mysqld.inc
DROP TABLE u1,u2,u3,u6;
--remove_file $MYSQLD_DATADIR/test/u4.ibd
--echo # List of files:
--list_files $MYSQLD_DATADIR/test
SHOW TABLES;
|