Skip to content

Commit 4e3e503

Browse files
author
Mohammad Tafzeel Shams
committed
BUG #33459653 : coredump after add index for partion table with ibd
file missing Problem: - If we delete .ibd file of a partition along with the 1st partition then after restart when we open the partition table we get the error message, which is the expected behaviour. - When we delete .ibd file of a partition other than the 1st partition then after restart when we open the partition table we hit the debug assert because ha_innopart::open() checks for ibd_file_missing only for the 1st partition. Solution: Instead of checking ibd_file_missing only for the 1st partition we check ibd_file_missing for all the partitions. Reviewed by : Marcin Babij (marcin.babij@oracle.com) RB #27494
1 parent 0918169 commit 4e3e503

File tree

4 files changed

+89
-27
lines changed

4 files changed

+89
-27
lines changed

mysql-test/suite/innodb/r/innodb-import-partition.result

+5
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ c1
954954
64
955955
Warnings:
956956
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
957+
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
957958
SELECT * FROM t1 ORDER BY c1;
958959
ERROR HY000: Tablespace has been discarded for table 't1'
959960
ALTER TABLE t1 DISCARD PARTITION TABLESPACE;
@@ -1102,6 +1103,10 @@ c1
11021103
164
11031104
Warnings:
11041105
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
1106+
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
1107+
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
1108+
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
1109+
Warning 1814 InnoDB: Tablespace has been discarded for table 't1'
11051110
SELECT * FROM t1 ORDER BY c1;
11061111
ERROR HY000: Tablespace has been discarded for table 't1'
11071112
ALTER TABLE t1 DISCARD PARTITION p1sp2 TABLESPACE;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CREATE TABLE table_33459653(ID INT NOT NULL AUTO_INCREMENT, Random INT NOT
2+
NULL, Text VARCHAR(200) NOT NULL, PRIMARY KEY(id))
3+
ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE (id) (
4+
PARTITION p1 VALUES LESS THAN (2000),
5+
PARTITION p2 VALUES LESS THAN (4000),
6+
PARTITION p3 VALUES LESS THAN (6000),
7+
PARTITION p4 VALUES LESS THAN MAXVALUE);
8+
# restart
9+
ALTER TABLE table_33459653 ADD INDEX index1(Random);
10+
ERROR 42S02: Table 'test.table_33459653' doesn't exist
11+
SELECT * FROM table_33459653 WHERE Random=1;
12+
ERROR 42S02: Table 'test.table_33459653' doesn't exist
13+
DROP TABLE table_33459653;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Test for BUG #33459653: Coredump after add index for partion table with ibd file missing.
2+
3+
--source include/have_innodb.inc
4+
5+
let $MYSQLD_DATADIR=`SELECT @@datadir`;
6+
7+
CREATE TABLE table_33459653(ID INT NOT NULL AUTO_INCREMENT, Random INT NOT
8+
NULL, Text VARCHAR(200) NOT NULL, PRIMARY KEY(id))
9+
ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE (id) (
10+
PARTITION p1 VALUES LESS THAN (2000),
11+
PARTITION p2 VALUES LESS THAN (4000),
12+
PARTITION p3 VALUES LESS THAN (6000),
13+
PARTITION p4 VALUES LESS THAN MAXVALUE);
14+
15+
--source include/shutdown_mysqld.inc
16+
17+
# REMOVE p4's .ibd file
18+
remove_file $MYSQLD_DATADIR/test/table_33459653#P#p4.ibd;
19+
20+
--source include/start_mysqld.inc
21+
22+
--disable_query_log
23+
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number 2 in a file operation.");
24+
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified.");
25+
call mtr.add_suppression("\\[ERROR\\] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.");
26+
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot open datafile for read-only: './test/table_33459653#P#p4.ibd' OS error: 71");
27+
call mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to find tablespace for table `test`\.`table_33459653` .* in the cache.");
28+
call mtr.add_suppression("\\[ERROR\\] InnoDB: Could not find a valid tablespace file for `test/table_33459653#P#p4`.");
29+
call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace .* because it could not be opened");
30+
call mtr.add_suppression("\\[Warning\\] InnoDB: Cannot calculate statistics for table `test`\.`table_33459653` .* because the \.ibd file is missing");
31+
call mtr.add_suppression("\\[Warning\\] InnoDB: Missing \.ibd file for table `test`\.`table_33459653` .*");
32+
--enable_query_log
33+
34+
--error S42S02
35+
ALTER TABLE table_33459653 ADD INDEX index1(Random);
36+
37+
38+
--error S42S02
39+
SELECT * FROM table_33459653 WHERE Random=1;
40+
41+
DROP TABLE table_33459653;

storage/innobase/handler/ha_innopart.cc

+30-27
Original file line numberDiff line numberDiff line change
@@ -1049,8 +1049,6 @@ ha_innopart::open(
10491049
m_upd_buf = NULL;
10501050
m_upd_buf_size = 0;
10511051

1052-
/* Get pointer to a table object in InnoDB dictionary cache. */
1053-
ib_table = m_part_share->get_table_part(0);
10541052

10551053
m_pcur_parts = NULL;
10561054
m_clust_pcur_parts = NULL;
@@ -1080,43 +1078,48 @@ ha_innopart::open(
10801078

10811079
MONITOR_INC(MONITOR_TABLE_OPEN);
10821080

1083-
bool no_tablespace;
10841081

1085-
/* TODO: Should we do this check for every partition during ::open()? */
10861082
/* TODO: refactor this in ha_innobase so it can increase code reuse. */
1087-
if (dict_table_is_discarded(ib_table)) {
1083+
for (uint part_id = 0; part_id < m_tot_parts; part_id++) {
1084+
bool no_tablespace;
1085+
ib_table = m_part_share->get_table_part(part_id);
1086+
if (dict_table_is_discarded(ib_table)) {
10881087

1089-
ib_senderrf(thd,
1090-
IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED,
1091-
table->s->table_name.str);
1088+
ib_senderrf(thd,
1089+
IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED,
1090+
table->s->table_name.str);
10921091

1093-
/* Allow an open because a proper DISCARD should have set
1094-
all the flags and index root page numbers to FIL_NULL that
1095-
should prevent any DML from running but it should allow DDL
1096-
operations. */
1092+
/* Allow an open because a proper DISCARD should have set
1093+
all the flags and index root page numbers to FIL_NULL that
1094+
should prevent any DML from running but it should allow DDL
1095+
operations. */
10971096

1098-
no_tablespace = false;
1097+
no_tablespace = false;
10991098

1100-
} else if (ib_table->ibd_file_missing) {
1099+
} else if (ib_table->ibd_file_missing) {
11011100

1102-
ib_senderrf(
1103-
thd, IB_LOG_LEVEL_WARN,
1104-
ER_TABLESPACE_MISSING, norm_name);
1101+
ib_senderrf(
1102+
thd, IB_LOG_LEVEL_WARN,
1103+
ER_TABLESPACE_MISSING, norm_name);
11051104

1106-
/* This means we have no idea what happened to the tablespace
1107-
file, best to play it safe. */
1105+
/* This means we have no idea what happened to the tablespace
1106+
file, best to play it safe. */
11081107

1109-
no_tablespace = true;
1110-
} else {
1111-
no_tablespace = false;
1112-
}
1108+
no_tablespace = true;
1109+
} else {
1110+
no_tablespace = false;
1111+
}
11131112

1114-
if (!thd_tablespace_op(thd) && no_tablespace) {
1115-
set_my_errno(ENOENT);
1116-
close();
1117-
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
1113+
if (!thd_tablespace_op(thd) && no_tablespace) {
1114+
set_my_errno(ENOENT);
1115+
close();
1116+
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
1117+
}
11181118
}
11191119

1120+
/* Get pointer to a table object in InnoDB dictionary cache. */
1121+
ib_table = m_part_share->get_table_part(0);
1122+
11201123
m_prebuilt = row_create_prebuilt(ib_table, table->s->reclength);
11211124

11221125
m_prebuilt->default_rec = table->s->default_values;

0 commit comments

Comments
 (0)