summaryrefslogtreecommitdiff
path: root/mysql-test/suite/gcol
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-02-01 18:36:03 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-02-01 18:53:41 +0200
commit44314c768f45ff7f0ad5d1133f4fd9ae0df12585 (patch)
tree4bb6f910b2636cfec3b4f6c8ee40019a1ca92a08 /mysql-test/suite/gcol
parent29240b50e3249f7905898b3332b82a1e98ff9355 (diff)
downloadmariadb-git-44314c768f45ff7f0ad5d1133f4fd9ae0df12585.tar.gz
MDEV-15165 InnoDB purge for index on virtual column is trying to access an incomplete record
The algorithm change is based on a MySQL 8.0 fix for BUG #26818787: ASSERTION: DATA0DATA.IC:430:TUPLE by Krzysztof Kapuścik https://github.com/mysql/mysql-server/commit/ee606e62bbddd7ac3579b4a20ef8684fa7cd83fe If a record had been inserted in place of a delete-marked purgeable record by modifying that record, and purge was accessing that record before the off-page columns were written, row_build_index_entry() would have returned NULL, causing a crash. row_vers_non_virtual_fields_equal(): Check whether all non-virtual fields of an index are equal. Replaces row_vers_non_vc_match(). A more complex version of this function was called row_vers_non_vc_index_entry_match() in the MySQL 8.0 fix. row_vers_impl_x_locked_low(): This change is not directly related to the reported problem, but apparently to the removal of the function row_vers_non_vc_match(). This function checks if a secondary index record was modified by a transaction that has not been committed yet. For comparing the non-virtual columns, construct a secondary index tuple from the table row. row_vers_vc_matches_cluster(): Replace row_vers_non_vc_match() with code that is equivalent to the row_vers_non_vc_index_entry_match() in the MySQL 8.0 fix. Also, deduplicate some code by using goto.
Diffstat (limited to 'mysql-test/suite/gcol')
-rw-r--r--mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result26
-rw-r--r--mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test29
2 files changed, 53 insertions, 2 deletions
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
index ac4be0dcc6c..309d8e8f04a 100644
--- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
+++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
@@ -145,7 +145,8 @@ connection default;
update t set a = repeat('m', 16000) where a like "aaa%";
connect lock_table, localhost, root;
lock table t write;
-disconnect prevent_purge;
+connection prevent_purge;
+commit;
connection default;
InnoDB 0 transactions not purged
disconnect lock_table;
@@ -154,5 +155,28 @@ commit;
InnoDB 0 transactions not purged
set global debug_dbug=@old_dbug;
drop table t;
+#
+# MDEV-15165 InnoDB purge for index on virtual column
+# is trying to access an incomplete record
+#
+CREATE TABLE t1(
+u INT PRIMARY KEY, b BLOB, ug INT GENERATED ALWAYS AS (u) VIRTUAL,
+INDEX bug(b(100),ug)
+) ENGINE=InnoDB;
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+start transaction with consistent snapshot;
+connection default;
+DELETE FROM t1;
+SET DEBUG_SYNC='blob_write_middle SIGNAL halfway WAIT_FOR purged';
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+SET DEBUG_SYNC='now WAIT_FOR halfway';
+COMMIT;
+InnoDB 0 transactions not purged
+SET DEBUG_SYNC='now SIGNAL purged';
+disconnect prevent_purge;
+connection default;
+DROP TABLE t1;
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
index 1862de268af..ad733eee3a7 100644
--- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
+++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
@@ -184,7 +184,8 @@ connection default;
update t set a = repeat('m', 16000) where a like "aaa%";
connect(lock_table, localhost, root);
lock table t write;
-disconnect prevent_purge;
+connection prevent_purge;
+commit;
connection default;
--source ../../innodb/include/wait_all_purged.inc
disconnect lock_table;
@@ -194,6 +195,32 @@ commit;
set global debug_dbug=@old_dbug;
drop table t;
+--echo #
+--echo # MDEV-15165 InnoDB purge for index on virtual column
+--echo # is trying to access an incomplete record
+--echo #
+CREATE TABLE t1(
+ u INT PRIMARY KEY, b BLOB, ug INT GENERATED ALWAYS AS (u) VIRTUAL,
+ INDEX bug(b(100),ug)
+) ENGINE=InnoDB;
+INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+start transaction with consistent snapshot;
+connection default;
+DELETE FROM t1;
+SET DEBUG_SYNC='blob_write_middle SIGNAL halfway WAIT_FOR purged';
+send INSERT INTO t1 (u,b) VALUES(1,REPEAT('a',16384));
+connection prevent_purge;
+SET DEBUG_SYNC='now WAIT_FOR halfway';
+COMMIT;
+--source ../../innodb/include/wait_all_purged.inc
+SET DEBUG_SYNC='now SIGNAL purged';
+disconnect prevent_purge;
+
+connection default;
+reap;
+DROP TABLE t1;
+
--source include/wait_until_count_sessions.inc
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;