From 7d04ce6a2d42770fcc765d257c0058a859180b80 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Thu, 14 Jan 2021 18:18:06 +0200 Subject: MDEV-21153 Replica nodes crash due to indexed virtual columns and FK cascading delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for MDEV-23033 fixes a problem in replication applying of transactions, which contain cascading foreign key delete for a table, which has indexed virtual column. This fix adds slave_fk_event_map flag for table, to mark when the prelocking is needed for applying of a transaction. See commit 608b0ee52ef3e854ce14a407e64e936adbbeba23 for more details. However, this fix is targeted for async replication only, Rows_log_event::do_apply_event() has condition to rule out galera replication from the fix domain, and use cases suffering from MDEV-23033 and related MDEV-21153 will fail in galera cluster. The fix in this commit removes the condition to rule out the setting of slave_fk_event_map flag from galera replication, and makes the fix in MDEV-23033 effective for galera replication as well. Finally, a mtr test for virtual column support has been added. galera.galera_virtual_column.test has as first test a scenario from MDEV-21153 Reviewed-by: Jan Lindström --- .../suite/galera/r/galera_virtual_column.result | 17 +++++++++ .../suite/galera/t/galera_virtual_column.test | 42 ++++++++++++++++++++++ sql/log_event.cc | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_virtual_column.result create mode 100644 mysql-test/suite/galera/t/galera_virtual_column.test diff --git a/mysql-test/suite/galera/r/galera_virtual_column.result b/mysql-test/suite/galera/r/galera_virtual_column.result new file mode 100644 index 00000000000..c4b425964c5 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_virtual_column.result @@ -0,0 +1,17 @@ +connection node_1; +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); +connection node_2; +connection node_1; +DELETE FROM p WHERE id=1; +SELECT * FROM p; +id +SELECT * FROM c; +id pid bitmap bitmap5 +connection node_2; +connection node_1; +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/t/galera_virtual_column.test b/mysql-test/suite/galera/t/galera_virtual_column.test new file mode 100644 index 00000000000..84e1da024f1 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_virtual_column.test @@ -0,0 +1,42 @@ +# +# This test is for testing virtual columnm support in galera cluster +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# test case for verifying that cascaded delete in a table with virtual column does not crash slave node +# + +--connection node_1 + +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); + +# not sure of this index is needed for the test +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; + +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); + + +--connection node_2 +# wait until both INSERTS have arrived in node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM c +--source include/wait_condition.inc + +--connection node_1 +# delete from parent table, it will cascade into child table +# node_2 might have problem in applying this cascaded delete +DELETE FROM p WHERE id=1; + +SELECT * FROM p; +SELECT * FROM c; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM c; +--source include/wait_condition.inc + +--connection node_1 +DROP TABLE c; +DROP TABLE p; diff --git a/sql/log_event.cc b/sql/log_event.cc index 48a25c8ba3d..e344fc8894f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11357,7 +11357,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) tables->trg_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; } - else if (!WSREP_ON) + else { tables->slave_fk_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; -- cgit v1.2.1