Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions mysql-test/main/partition_alter.result
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,16 @@ Level Code Message
Error 1845 ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE
drop table t1par;
set alter_algorithm=@old_alter_algorithm;
#
# MDEV-33170 ASAN errors upon CONVERT TABLE TO PARTITION with query cache
#
SET @qcache= @@global.query_cache_type;
SET GLOBAL query_cache_type= 1;
CREATE TABLE t (a INT) PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1));
CREATE TABLE t1 (a INT);
ALTER TABLE t CONVERT TABLE t1 TO PARTITION pn VALUES IN (2);
DROP TABLE IF EXISTS t1, t;
Warnings:
Note 1051 Unknown table 'test.t1'
SET GLOBAL query_cache_type= @qcache;
# End of 10.11 tests
17 changes: 17 additions & 0 deletions mysql-test/main/partition_alter.test
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_query_cache.inc

CREATE TABLE `test_data` (
`hid` bigint(20) unsigned NOT NULL,
Expand Down Expand Up @@ -348,4 +349,20 @@ show warnings;
drop table t1par;
set alter_algorithm=@old_alter_algorithm;


--echo #
--echo # MDEV-33170 ASAN errors upon CONVERT TABLE TO PARTITION with query cache
--echo #

SET @qcache= @@global.query_cache_type;
SET GLOBAL query_cache_type= 1;

CREATE TABLE t (a INT) PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1));
CREATE TABLE t1 (a INT);
ALTER TABLE t CONVERT TABLE t1 TO PARTITION pn VALUES IN (2);

# Cleanup
DROP TABLE IF EXISTS t1, t;
SET GLOBAL query_cache_type= @qcache;

--echo # End of 10.11 tests
4 changes: 2 additions & 2 deletions sql/sql_partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4631,8 +4631,6 @@ static int fast_end_partition(THD *thd, ulonglong copied,

thd->proc_info="end";

query_cache_invalidate3(thd, table_list, 0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Removing query_cache_invalidate3 from fast_end_partition introduces a regression for other fast partition operations (e.g., ADD PARTITION, DROP PARTITION, REORGANIZE PARTITION). Since fast_end_partition is the common exit point for all fast partition alterations, these operations will no longer invalidate the query cache, leading to stale results. To fix the Use-After-Free while maintaining correctness, the invalidation should be moved to a common point at the beginning of fast_alter_partition_table to ensure all operations are covered and the cache is invalidated before any tables are closed or freed.


my_snprintf(tmp_name, sizeof(tmp_name), ER_THD(thd, ER_INSERT_INFO),
(ulong) (copied + deleted),
(ulong) deleted,
Expand Down Expand Up @@ -7733,6 +7731,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
check_table_data(lpt))
goto err;

query_cache_invalidate3(thd, table_list, 0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While moving the invalidation here fixes the Use-After-Free for the CONVERT_IN case, it is incomplete as it doesn't cover other operations previously handled by fast_end_partition. Furthermore, to prevent potential Use-After-Free issues in subsequent invalidation calls (such as the one at the end of mysql_alter_table), any TABLE pointers in table_list that are closed or freed during the operation should be explicitly set to NULL.


if (write_log_drop_shadow_frm(lpt) ||
ERROR_INJECT("convert_partition_3") ||
mysql_write_frm(lpt, WFRM_WRITE_SHADOW) ||
Expand Down