mirror of
https://github.com/MariaDB/server.git
synced 2025-08-09 22:24:09 +03:00
The problem was that TRUNCATE TABLE didn't take a exclusive lock on a table if it resorted to truncating via delete of all rows in the table. Specifically for InnoDB tables, this could break proper isolation as InnoDB ends up aborting some granted locks when truncating a table. The solution is to take a exclusive metadata lock before TRUNCATE TABLE can proceed. This guarantees that no other transaction is using the table. Incompatible change: Truncate via delete no longer fails if sql_safe_updates is activated (this was a undocumented side effect).
58 lines
1.1 KiB
Plaintext
58 lines
1.1 KiB
Plaintext
#
|
|
# Bug#38231 Innodb crash in lock_reset_all_on_table() on TRUNCATE + LOCK / UNLOCK
|
|
# http://bugs.mysql.com/38231
|
|
#
|
|
|
|
-- source include/have_innodb.inc
|
|
|
|
SET storage_engine=InnoDB;
|
|
|
|
# we care only that the following SQL commands do not crash the server
|
|
-- disable_query_log
|
|
-- disable_result_log
|
|
|
|
DROP TABLE IF EXISTS bug38231;
|
|
CREATE TABLE bug38231 (a INT);
|
|
|
|
-- connect (con1,localhost,root,,)
|
|
-- connect (con2,localhost,root,,)
|
|
|
|
-- connection con1
|
|
SET autocommit=0;
|
|
LOCK TABLE bug38231 WRITE;
|
|
|
|
-- connection con2
|
|
SET autocommit=0;
|
|
-- send
|
|
LOCK TABLE bug38231 WRITE;
|
|
|
|
-- connection default
|
|
-- send
|
|
TRUNCATE TABLE bug38231;
|
|
|
|
-- connection con1
|
|
# give time to TRUNCATE and others to be executed; without sleep, sometimes
|
|
# UNLOCK executes before TRUNCATE
|
|
# TODO: Replace with wait_condition once possible under embedded server.
|
|
-- sleep 0.2
|
|
# this crashes the server if the bug is present
|
|
UNLOCK TABLES;
|
|
|
|
# clean up
|
|
|
|
-- connection con2
|
|
-- reap
|
|
UNLOCK TABLES;
|
|
|
|
-- connection default
|
|
-- reap
|
|
-- disconnect con1
|
|
-- disconnect con2
|
|
|
|
-- enable_query_log
|
|
-- enable_result_log
|
|
|
|
-- connection default
|
|
|
|
DROP TABLE bug38231;
|