mirror of
https://github.com/MariaDB/server.git
synced 2025-11-25 17:25:02 +03:00
This is a backport of161e4bfafd. trans_rollback_to_savepoint(): Only release metadata locks (MDL) if the storage engines agree, after the changes were already rolled back. Ever since commit3792693f31and mysql/mysql-server@55ceedbc3f we used to cheat here and always release MDL if the binlog is disabled. MDL are supposed to prevent race conditions between DML and DDL also when no replication is in use. MDL are supposed to be a superset of InnoDB table locks: InnoDB table lock may only exist if the thread also holds MDL on the table name. In the included test case, ROLLBACK TO SAVEPOINT would wrongly release the MDL on both tables and let ALTER TABLE proceed, even though the DML transaction is actually holding locks on the table. Until commit1bd681c8b3(MDEV-25506) in MariaDB 10.6, InnoDB would often work around the locking violation in a blatantly non-ACID way: If locks exist on a table that is being dropped (in this case, actually a partition of a table that is being rebuilt by ALTER TABLE), InnoDB could move the table (or partition) into a queue, to be dropped after the locks and references had been released. If the lock is not released and the original copy of the table not dropped quickly enough, a name conflict could occur on a subsequent ALTER TABLE. The scenario of commit3792693f31is unaffected by this fix, because mysqldump would use non-locking reads, and the transaction would not be holding any InnoDB locks during the execution of ROLLBACK TO SAVEPOINT. MVCC reads inside InnoDB are only covered by MDL and page latches, not by any table or record locks. FIXME: It would be nice if storage engines were specifically asked which MDL can be released, instead of only offering a choice between all or nothing. InnoDB should be able to release any locks for tables that are no longer in trx_t::mod_tables, except if another transaction had converted some implicit record locks to explicit ones, before the ROLLBACK TO SAVEPOINT had been completed. Reviewed by: Sergei Golubchik
37 lines
813 B
Plaintext
37 lines
813 B
Plaintext
--source include/have_innodb.inc
|
|
--source include/have_partition.inc
|
|
|
|
--echo #
|
|
--echo # MDEV-26077 Assertion failure err != DB_DUPLICATE_KEY
|
|
--echo # or unexpected ER_TABLE_EXISTS_ERROR
|
|
--echo #
|
|
|
|
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
|
|
CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=InnoDB;
|
|
|
|
--connect (con1,localhost,root,,test)
|
|
|
|
START TRANSACTION;
|
|
INSERT INTO t2 (pk) VALUES (1);
|
|
SAVEPOINT sp;
|
|
INSERT INTO t1 (pk) VALUES (1);
|
|
ROLLBACK TO SAVEPOINT sp;
|
|
|
|
--connection default
|
|
SET lock_wait_timeout=0;
|
|
SET innodb_lock_wait_timeout=0;
|
|
--error ER_LOCK_WAIT_TIMEOUT
|
|
ALTER TABLE t1 PARTITION BY HASH(pk);
|
|
|
|
SHOW CREATE TABLE t1;
|
|
--connection con1
|
|
COMMIT;
|
|
--connection default
|
|
ALTER TABLE t2 PARTITION BY HASH(pk);
|
|
# Cleanup
|
|
--disconnect con1
|
|
--connection default
|
|
DROP TABLE t1, t2;
|
|
|
|
--echo # End of 10.2 tests
|