summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_purge.result17
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_purge.test35
-rw-r--r--storage/innobase/row/row0purge.cc8
3 files changed, 60 insertions, 0 deletions
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result
index 308b01ded25..ee88527ec2e 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_purge.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result
@@ -142,4 +142,21 @@ CREATE TABLE t1 (a VARCHAR(30), b INT, a2 VARCHAR(30) GENERATED ALWAYS AS (a) VI
CREATE INDEX idx ON t1(a2(10), b, a2(20));
ERROR 42S21: Duplicate column name 'a2'
DROP TABLE t1;
+#
+# MDEV-17540 Server crashes in row_purge after TRUNCATE TABLE
+#
+CREATE TABLE t1 (a BIT(14)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(b'01110110101011'),(b'01100111111000'),(b'00001011110100'),
+(b'01110110111010'),(b'10001010101011'),(b'01100111001111');
+CREATE TABLE t2 (
+pk INT DEFAULT 1,
+b YEAR,
+c BIT(14),
+d YEAR AS (b),
+e BIT(14) AS (c),
+UNIQUE(pk),
+KEY(e)
+) ENGINE=InnoDB;
+DROP TABLE t1, t2;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test
index 4eb5d8c65b8..c79a817dd4e 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_purge.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test
@@ -137,5 +137,40 @@ CREATE INDEX idx ON t1(a2(10), b, a2(20));
DROP TABLE t1;
+--echo #
+--echo # MDEV-17540 Server crashes in row_purge after TRUNCATE TABLE
+--echo #
+
+# Note: this test case is nondeterministic and should depend on
+# MDEV-12288 to trigger the needed purge activity.
+# The test does not seem to repeat the bug on MariaDB 10.2.
+
+CREATE TABLE t1 (a BIT(14)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ (b'01110110101011'),(b'01100111111000'),(b'00001011110100'),
+ (b'01110110111010'),(b'10001010101011'),(b'01100111001111');
+
+CREATE TABLE t2 (
+ pk INT DEFAULT 1,
+ b YEAR,
+ c BIT(14),
+ d YEAR AS (b),
+ e BIT(14) AS (c),
+ UNIQUE(pk),
+ KEY(e)
+) ENGINE=InnoDB;
+
+# Run a few times in order to improve the chances of triggering the bug.
+--disable_query_log
+let $n=10;
+while ($n) {
+REPLACE INTO t2 (c) SELECT a FROM t1;
+TRUNCATE TABLE t2;
+dec $n;
+}
+--enable_query_log
+
+DROP TABLE t1, t2;
+
--source include/wait_until_count_sessions.inc
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index f5078c5dffb..bd709f98b08 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -824,6 +824,14 @@ row_purge_upd_exist_or_extern_func(
node->row, NULL, node->index,
heap, ROW_BUILD_FOR_PURGE);
row_purge_remove_sec_if_poss(node, node->index, entry);
+
+ if (node->vcol_op_failed()) {
+ ut_ad(!node->table);
+ mem_heap_free(heap);
+ return;
+ }
+ ut_ad(node->table);
+
mem_heap_empty(heap);
}