Skip to content

Commit dea5746

Browse files
committed
MDEV-32155 MariaDB Server crashes with ill-formed partitions
for ALTER_PARTITION_ADMIN (CHECK/REPAIR/LOAD INDEX/CACHE INDEX/etc) partitioning marks affected partitions with PART_ADMIN state. The assumption is that the server will call a corresponding method of ha_partition which will reset the state back to PART_NORMAL. This assumption is invalid, the server is not required to do so, indeed, in CHECK ... FOR UPGRADE the server might decide early that the table is fine and won't call ha_partition::check(), leaving partitions in the wrong state. It will thus leak into the next statement confusing the engine about what it is doing (see ha_partition::create_handler_file()), causing a crash later. Let's force all partitions into PART_NORMAL state after the admin operation succeeded, in case it did so without consulting the engine.
1 parent 8ac3051 commit dea5746

File tree

5 files changed

+29
-10
lines changed

5 files changed

+29
-10
lines changed

mysql-test/main/partition_key_cache.result

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
DROP TABLE IF EXISTS t1, t2, v, x;
21
# Actual test of key caches
32
# Verifing that reads/writes use the key cache correctly
43
SET @org_key_cache_buffer_size= @@global.default.key_buffer_size;

mysql-test/main/partition_key_cache.test

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# Test of key cache with partitions
22
--source include/have_partition.inc
33

4-
--disable_warnings
5-
DROP TABLE IF EXISTS t1, t2, v, x;
6-
--enable_warnings
7-
84
--echo # Actual test of key caches
95
--echo # Verifing that reads/writes use the key cache correctly
106
SET @org_key_cache_buffer_size= @@global.default.key_buffer_size;

mysql-test/main/partition_mgm_err.result

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
drop table if exists t1;
21
CREATE TABLE t1 (a int, b int)
32
PARTITION BY RANGE (a)
43
(PARTITION x0 VALUES LESS THAN (2),
@@ -158,3 +157,15 @@ PARTITION p1 VALUES IN (0) (SUBPARTITION p1b),
158157
PARTITION p2 VALUES IN (2) (SUBPARTITION p1b)
159158
);
160159
ERROR HY000: Duplicate partition name p1b
160+
# End of 5.5 tests
161+
#
162+
# MDEV-32155 MariaDB Server crashes with ill-formed partitions
163+
#
164+
create table t1 (c1 set ( 'abc' ) binary unicode) partition by linear hash (c1 mod c1) partitions 10;
165+
alter table t1 check partition all for upgrade;
166+
Table Op Msg_type Msg_text
167+
test.t1 check status OK
168+
alter table t1 order by nonexistent;
169+
ERROR 42S22: Unknown column 'nonexistent' in 'order clause'
170+
drop table t1;
171+
# End of 10.5 tests

mysql-test/main/partition_mgm_err.test

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
#
55
-- source include/have_partition.inc
66

7-
--disable_warnings
8-
drop table if exists t1;
9-
--enable_warnings
10-
117
#
128
# Try faulty DROP PARTITION and COALESCE PARTITION
139
#
@@ -223,3 +219,16 @@ SUBPARTITION BY KEY (s2) (
223219
PARTITION p1 VALUES IN (0) (SUBPARTITION p1b),
224220
PARTITION p2 VALUES IN (2) (SUBPARTITION p1b)
225221
);
222+
223+
--echo # End of 5.5 tests
224+
225+
--echo #
226+
--echo # MDEV-32155 MariaDB Server crashes with ill-formed partitions
227+
--echo #
228+
create table t1 (c1 set ( 'abc' ) binary unicode) partition by linear hash (c1 mod c1) partitions 10;
229+
alter table t1 check partition all for upgrade;
230+
--error ER_BAD_FIELD_ERROR
231+
alter table t1 order by nonexistent;
232+
drop table t1;
233+
234+
--echo # End of 10.5 tests

sql/sql_admin.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
875875
result_code = (table->table->file->*operator_func)(thd, check_opt);
876876
THD_STAGE_INFO(thd, stage_sending_data);
877877
DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
878+
#ifdef WITH_PARTITION_STORAGE_ENGINE
879+
if (lex->alter_info.partition_flags & ALTER_PARTITION_ADMIN)
880+
set_part_state(&lex->alter_info, table->table->part_info, PART_NORMAL);
881+
#endif
878882
}
879883

880884
if (compl_result_code == HA_ADMIN_OK && collect_eis)

0 commit comments

Comments
 (0)