summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/innodb/t/import_recovery.test
blob: ebaa25ff97ccc0a5937e1cfbb3829d30863314ed (plain)
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
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/not_embedded.inc

--echo #
--echo # MDEV-26137 ALTER TABLE IMPORT enhancement
--echo #

let MYSQLD_DATADIR = `SELECT @@datadir`;
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;

call mtr.add_suppression('InnoDB: Tablespace for table `test`.`t1` is set as discarded.');
call mtr.add_suppression('InnoDB: Tablespace for table `test`.`t2` is set as discarded.');
call mtr.add_suppression('InnoDB: Tablespace for table `test`.`t3` is set as discarded.');
call mtr.add_suppression('InnoDB: ./test/t3.ibd: Page 0 at offset 0 looks corrupted.');
call mtr.add_suppression("mariadbd.*: Index for table 't3' is corrupt; try to repair it");
call mtr.add_suppression("InnoDB: Expected tablespace id \\d+ but found \\d+ in the file ./test/t3.ibd");
# In Windows etc.
call mtr.add_suppression("InnoDB: Corrupted page \\[page id: space=.*, page number=0\\] of datafile './test/t3.ibd' could not be found in the doublewrite buffer.");
call mtr.add_suppression('InnoDB: Tablespace for table `test`.`t4` is set as discarded.');
call mtr.add_suppression('InnoDB: ./test/t4.ibd: Page 0 at offset 0 looks corrupted.');
call mtr.add_suppression("mariadbd.*: Index for table 't4' is corrupt; try to repair it");
# In Windows etc.
call mtr.add_suppression("InnoDB: Corrupted page \\[page id: space=.*, page number=0\\] of datafile './test/t4.ibd' could not be found in the doublewrite buffer.");

--echo # Recovery from crashes
--echo ## t1: Creation of stub succeeds; server crashes; second import attempt succeeds
--echo ## t2: Creation of stub succeeds; server crashes; drop table
--echo ## t3: Creation of stub succeeds; server crashes; ibd corrupted; second import attempt fails; drop table
--echo ## t4: Did not copy .cfg; creation of stub succeeds; server crashes; ibd corrupted; second import attempt fails; drop table
CREATE TABLE t (a int) ENGINE=InnoDB;
INSERT INTO t VALUES(42);
FLUSH TABLES t FOR EXPORT;
--copy_file $MYSQLD_DATADIR/test/t.cfg $MYSQLD_DATADIR/test/t1.cfg
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t1.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t1.ibd
--copy_file $MYSQLD_DATADIR/test/t.cfg $MYSQLD_DATADIR/test/t2.cfg
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t2.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t2.ibd
--copy_file $MYSQLD_DATADIR/test/t.cfg $MYSQLD_DATADIR/test/t3.cfg
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t3.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t3.ibd
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t4.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t4.ibd
UNLOCK TABLES;

SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
SET GLOBAL innodb_max_dirty_pages_pct=0.0;

let $wait_condition =
SELECT variable_value = 0
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY';
--source include/wait_condition.inc

connect (hang1,localhost,root);
SET DEBUG_SYNC='ib_after_create_stub_for_import SIGNAL hung WAIT_FOR ever';
send ALTER TABLE t1 IMPORT TABLESPACE;
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';

connect (hang2,localhost,root);
SET DEBUG_SYNC='ib_after_create_stub_for_import SIGNAL hung WAIT_FOR ever';
send ALTER TABLE t2 IMPORT TABLESPACE;
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';

connect (hang3,localhost,root);
SET DEBUG_SYNC='ib_after_create_stub_for_import SIGNAL hung WAIT_FOR ever';
send ALTER TABLE t3 IMPORT TABLESPACE;
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';

connect (hang4,localhost,root);
SET DEBUG_SYNC='ib_after_create_stub_for_import SIGNAL hung WAIT_FOR ever';
send ALTER TABLE t4 IMPORT TABLESPACE;
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';

let $shutdown_timeout=0;
--source include/shutdown_mysqld.inc

--echo # corrupting the 0th page
perl;
my $ps = $ENV{INNODB_PAGE_SIZE};

@tables= ('t3', 't4');
foreach $table (@tables) {
  my $file = "$ENV{MYSQLD_DATADIR}/test/$table.ibd";
  open(FILE, "+<$file") || die "Unable to open $file";
  binmode FILE;
  sysseek(FILE, 0, 0) || die "Unable to seek $file\n";
  die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
  # Replace all NUL bytes with SOH bytes.
  $page =~ tr/\x0/\x1/;
  sysseek(FILE, 0, 0) || die "Unable to seek $file\n";
  syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
  close FILE or die "close";
}
EOF

--echo # Restart mysqld after the crash and reconnect.
--source include/start_mysqld.inc

ALTER TABLE t1 IMPORT TABLESPACE;
SHOW CREATE TABLE t1;
SELECT * FROM t1;

--error ER_INTERNAL_ERROR
ALTER TABLE t3 IMPORT TABLESPACE;

--error ER_TABLE_SCHEMA_MISMATCH
ALTER TABLE t4 IMPORT TABLESPACE;

DROP TABLE t, t1, t2, t3, t4;

--echo # Recovery from corruption only, no server restart
--echo ## t5: Recovery from corruption, with cfg
--echo ## t6: Recovery from corruption, without cfg
call mtr.add_suppression('InnoDB: ./test/t5.ibd: Page 0 at offset 0 looks corrupted.');
call mtr.add_suppression("mariadbd.*: Index for table 't5' is corrupt; try to repair it");
# In Windows etc.
call mtr.add_suppression("InnoDB: Corrupted page \\[page id: space=.*, page number=0\\] of datafile './test/t5.ibd' could not be found in the doublewrite buffer.");
# In Windows etc.
call mtr.add_suppression("InnoDB: Corrupted page \\[page id: space=.*, page number=0\\] of datafile './test/t6.ibd' could not be found in the doublewrite buffer.");
call mtr.add_suppression("mariadbd.*: Index for table 't6' is corrupt; try to repair it");

CREATE TABLE t (a int) ENGINE=InnoDB;
INSERT INTO t VALUES(42);
FLUSH TABLES t FOR EXPORT;
--copy_file $MYSQLD_DATADIR/test/t.cfg $MYSQLD_DATADIR/test/t5.cfg
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t5.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t5.ibd
--copy_file $MYSQLD_DATADIR/test/t.frm $MYSQLD_DATADIR/test/t6.frm
--copy_file $MYSQLD_DATADIR/test/t.ibd $MYSQLD_DATADIR/test/t6.ibd
UNLOCK TABLES;

--echo # corrupting the 0th page
perl;
my $ps = $ENV{INNODB_PAGE_SIZE};

@tables= ('t5', 't6');
foreach $table (@tables) {
  my $file = "$ENV{MYSQLD_DATADIR}/test/$table.ibd";
  open(FILE, "+<$file") || die "Unable to open $file";
  binmode FILE;
  sysseek(FILE, 0, 0) || die "Unable to seek $file\n";
  die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
  # Replace all NUL bytes with SOH bytes.
  $page =~ tr/\x0/\x1/;
  sysseek(FILE, 0, 0) || die "Unable to seek $file\n";
  syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
  close FILE or die "close";
}
EOF

--error ER_INTERNAL_ERROR
ALTER TABLE t5 IMPORT TABLESPACE;

--error ER_TABLE_SCHEMA_MISMATCH
ALTER TABLE t6 IMPORT TABLESPACE;

DROP TABLE t, t5, t6;