diff options
-rw-r--r-- | mysql-test/suite/gcol/r/innodb_virtual_purge.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/gcol/t/innodb_virtual_purge.test | 35 | ||||
-rw-r--r-- | storage/innobase/row/row0purge.cc | 8 |
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); } |