summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/truncate_crash.result11
-rw-r--r--mysql-test/suite/innodb/t/truncate_crash.test12
-rw-r--r--storage/innobase/handler/ha_innodb.cc7
3 files changed, 29 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb/r/truncate_crash.result b/mysql-test/suite/innodb/r/truncate_crash.result
index 10ce8e92ab6..e6b92b00671 100644
--- a/mysql-test/suite/innodb/r/truncate_crash.result
+++ b/mysql-test/suite/innodb/r/truncate_crash.result
@@ -1,3 +1,4 @@
+call mtr.add_suppression("InnoDB: \\(\\Too many concurrent transactions\\)\\ writing .*");
FLUSH TABLES;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1),(2);
@@ -12,3 +13,13 @@ COUNT(*)
0
TRUNCATE TABLE t1;
DROP TABLE t1;
+#
+# MDEV-25663 Double free of transaction during
+# truncate operation
+#
+CREATE TABLE t1 (a INT, b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
+SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx';
+TRUNCATE table t1;
+ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
+SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/truncate_crash.test b/mysql-test/suite/innodb/t/truncate_crash.test
index 5cb39c745dc..475822dab28 100644
--- a/mysql-test/suite/innodb/t/truncate_crash.test
+++ b/mysql-test/suite/innodb/t/truncate_crash.test
@@ -3,6 +3,7 @@
--source include/have_debug_sync.inc
--source include/not_embedded.inc
+call mtr.add_suppression("InnoDB: \\(\\Too many concurrent transactions\\)\\ writing .*");
FLUSH TABLES;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1),(2);
@@ -21,3 +22,14 @@ disconnect wait;
SELECT COUNT(*) FROM t1;
TRUNCATE TABLE t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-25663 Double free of transaction during
+--echo # truncate operation
+--echo #
+CREATE TABLE t1 (a INT, b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
+SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx';
+--error ER_GET_ERRNO
+TRUNCATE table t1;
+SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
+DROP TABLE t1;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 2f02fa31c98..89822faf84e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -12830,7 +12830,6 @@ create_table_info_t::create_table_update_dict()
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
dict_table_close(innobase_table, FALSE, FALSE);
srv_active_wake_master_thread();
- m_trx->free();
DBUG_RETURN(-1);
}
@@ -12979,6 +12978,12 @@ ha_innobase::create(
error = info.create_table_update_dict();
+ /* In case of error, free the transaction only if
+ it is newly created transaction in ha_innobase::create() */
+ if (own_trx && error) {
+ info.trx()->free();
+ }
+
/* Tell the InnoDB server that there might be work for
utility threads: */