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.
This commit is contained in:
Sergei Golubchik 2024-06-16 18:04:27 +02:00
parent 8ac30517af
commit dea5746de2
5 changed files with 29 additions and 10 deletions

View File

@ -1,4 +1,3 @@
DROP TABLE IF EXISTS t1, t2, v, x;
# Actual test of key caches
# Verifing that reads/writes use the key cache correctly
SET @org_key_cache_buffer_size= @@global.default.key_buffer_size;

View File

@ -1,10 +1,6 @@
# Test of key cache with partitions
--source include/have_partition.inc
--disable_warnings
DROP TABLE IF EXISTS t1, t2, v, x;
--enable_warnings
--echo # Actual test of key caches
--echo # Verifing that reads/writes use the key cache correctly
SET @org_key_cache_buffer_size= @@global.default.key_buffer_size;

View File

@ -1,4 +1,3 @@
drop table if exists t1;
CREATE TABLE t1 (a int, b int)
PARTITION BY RANGE (a)
(PARTITION x0 VALUES LESS THAN (2),
@ -158,3 +157,15 @@ PARTITION p1 VALUES IN (0) (SUBPARTITION p1b),
PARTITION p2 VALUES IN (2) (SUBPARTITION p1b)
);
ERROR HY000: Duplicate partition name p1b
# End of 5.5 tests
#
# MDEV-32155 MariaDB Server crashes with ill-formed partitions
#
create table t1 (c1 set ( 'abc' ) binary unicode) partition by linear hash (c1 mod c1) partitions 10;
alter table t1 check partition all for upgrade;
Table Op Msg_type Msg_text
test.t1 check status OK
alter table t1 order by nonexistent;
ERROR 42S22: Unknown column 'nonexistent' in 'order clause'
drop table t1;
# End of 10.5 tests

View File

@ -4,10 +4,6 @@
#
-- source include/have_partition.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Try faulty DROP PARTITION and COALESCE PARTITION
#
@ -223,3 +219,16 @@ SUBPARTITION BY KEY (s2) (
PARTITION p1 VALUES IN (0) (SUBPARTITION p1b),
PARTITION p2 VALUES IN (2) (SUBPARTITION p1b)
);
--echo # End of 5.5 tests
--echo #
--echo # MDEV-32155 MariaDB Server crashes with ill-formed partitions
--echo #
create table t1 (c1 set ( 'abc' ) binary unicode) partition by linear hash (c1 mod c1) partitions 10;
alter table t1 check partition all for upgrade;
--error ER_BAD_FIELD_ERROR
alter table t1 order by nonexistent;
drop table t1;
--echo # End of 10.5 tests

View File

@ -875,6 +875,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
result_code = (table->table->file->*operator_func)(thd, check_opt);
THD_STAGE_INFO(thd, stage_sending_data);
DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (lex->alter_info.partition_flags & ALTER_PARTITION_ADMIN)
set_part_state(&lex->alter_info, table->table->part_info, PART_NORMAL);
#endif
}
if (compl_result_code == HA_ADMIN_OK && collect_eis)