mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Backport of revno: 2617.68.37
Bug #46654 False deadlock on concurrent DML/DDL with partitions, inconsistent behavior The problem was that if one connection is running a multi-statement transaction which involves a single partitioned table, and another connection attempts to alter the table, the first connection gets ER_LOCK_DEADLOCK and cannot proceed anymore, even when the ALTER TABLE statement in another connection has timed out or failed. The reason for this was that the prepare phase for ALTER TABLE for partitioned tables removed all instances of the table from the table definition cache before it started waiting on the lock. The transaction running in the first connection would notice this and report ER_LOCK_DEADLOCK. This patch changes the prep_alter_part_table() ALTER TABLE code so that tdc_remove_table() is no longer called. Instead, only the TABLE instance changed by prep_alter_part_table() is marked as needing reopen. The patch also removes an unnecessary call to tdc_remove_table() from mysql_unpack_partition() as the changed TABLE object is destroyed by the caller at a later point. Test case added in partition_sync.test.
This commit is contained in:
@@ -39,6 +39,57 @@
|
||||
#DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug #46654 False deadlock on concurrent DML/DDL
|
||||
--echo # with partitions, inconsistent behavior
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS tbl_with_partitions;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE tbl_with_partitions ( i INT )
|
||||
PARTITION BY HASH(i);
|
||||
INSERT INTO tbl_with_partitions VALUES (1);
|
||||
|
||||
connect(con2,localhost,root);
|
||||
connect(con3,localhost,root);
|
||||
|
||||
--echo # Connection 3
|
||||
connection con3;
|
||||
LOCK TABLE tbl_with_partitions READ;
|
||||
|
||||
--echo # Connection 1
|
||||
--echo # Access table with disabled autocommit
|
||||
connection default;
|
||||
SET AUTOCOMMIT = 0;
|
||||
SELECT * FROM tbl_with_partitions;
|
||||
|
||||
--echo # Connection 2
|
||||
--echo # Alter table, abort after prepare
|
||||
connection con2;
|
||||
set session debug="+d,abort_copy_table";
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE tbl_with_partitions ADD COLUMN f INT;
|
||||
|
||||
--echo # Connection 1
|
||||
--echo # Try accessing the table after Alter aborted.
|
||||
--echo # This used to give ER_LOCK_DEADLOCK.
|
||||
connection default;
|
||||
SELECT * FROM tbl_with_partitions;
|
||||
|
||||
--echo # Connection 3
|
||||
connection con3;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--echo # Connection 1
|
||||
--echo # Cleanup
|
||||
connection default;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
DROP TABLE tbl_with_partitions;
|
||||
|
||||
|
||||
# Check that all connections opened by test cases in this file are really
|
||||
# gone so execution of other tests won't be affected by their presence.
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
Reference in New Issue
Block a user