diff options
-rw-r--r-- | mysql-test/suite/galera/r/galera_virtual_column.result | 19 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_virtual_column.test | 42 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_schema.cc | 21 |
4 files changed, 83 insertions, 1 deletions
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..71820ed8225 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_virtual_column.result @@ -0,0 +1,19 @@ +connection node_2; +connection node_1; +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 e3079c5f9b9..20a41dc8aee 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11392,7 +11392,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; diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index 8a47bbec9b0..9a09fbc8902 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -899,6 +899,13 @@ int Wsrep_schema::append_fragment(THD* thd, thd->thread_id, os.str().c_str(), transaction_id.get()); + /* use private query table list for the duration of fragment storing, + populated query table list from "parent DML" may cause problems .e.g + for virtual column handling + */ + Query_tables_list query_tables_list_backup; + thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup); + Wsrep_schema_impl::binlog_off binlog_off(thd); Wsrep_schema_impl::init_stmt(thd); @@ -906,6 +913,7 @@ int Wsrep_schema::append_fragment(THD* thd, if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) { trans_rollback_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -919,9 +927,11 @@ int Wsrep_schema::append_fragment(THD* thd, if ((error= Wsrep_schema_impl::insert(frag_table))) { WSREP_ERROR("Failed to write to frag table: %d", error); trans_rollback_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(0); } @@ -938,6 +948,13 @@ int Wsrep_schema::update_fragment_meta(THD* thd, ws_meta.seqno().get()); DBUG_ASSERT(ws_meta.seqno().is_undefined() == false); + /* use private query table list for the duration of fragment storing, + populated query table list from "parent DML" may cause problems .e.g + for virtual column handling + */ + Query_tables_list query_tables_list_backup; + thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup); + Wsrep_schema_impl::binlog_off binlog_off(thd); int error; uchar key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; @@ -947,6 +964,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd, Wsrep_schema_impl::init_stmt(thd); if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) { + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -967,6 +985,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd, error); } Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -982,11 +1001,13 @@ int Wsrep_schema::update_fragment_meta(THD* thd, frag_table->s->table_name.str, error); Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } int ret= Wsrep_schema_impl::end_index_scan(frag_table); Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(ret); } |