diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 5a287e58d8a1a..eb1daa5a2d396 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -534,7 +534,6 @@ INSERT INTO t1 VALUES(1,1); ROLLBACK; SET DEBUG_SYNC = 'now SIGNAL inserted'; connection con1; -disconnect con1; connection default; SELECT * FROM t1; a b @@ -543,6 +542,31 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# MDEV-36281 DML aborts during online virtual index +# +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, f2 INT NOT NULL, +f3 INT NOT NULL, f4 INT AS (f3) VIRTUAL, +f5 INT AS (f1) VIRTUAL, INDEX(f4))ENGINE=InnoDB; +INSERT INTO t1(f1, f2, f3) VALUES(1, 2, 3); +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL dml_start WAIT_FOR dml_finish'; +ALTER TABLE t1 ADD INDEX v1(f5, f2, f4), ADD INDEX v2(f3, f5); +connection con1; +set DEBUG_SYNC="now WAIT_FOR dml_start"; +UPDATE t1 SET f3= f3 + 1; +set DEBUG_SYNC="now SIGNAL dml_finish"; +disconnect con1; +connection default; +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT f5, f2, f4 FROM t1 USE INDEX(v1); +f5 f2 f4 +1 2 4 +SELECT f3, f5 FROM t1 USE INDEX(v2); +f3 f5 +4 1 +DROP TABLE t1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig; SET GLOBAL innodb_monitor_enable = default; diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index 96ee31495186b..97ca25b1420c7 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -510,12 +510,35 @@ SET DEBUG_SYNC = 'now SIGNAL inserted'; connection con1; reap; -disconnect con1; connection default; SELECT * FROM t1; CHECK TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-36281 DML aborts during online virtual index +--echo # +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, f2 INT NOT NULL, + f3 INT NOT NULL, f4 INT AS (f3) VIRTUAL, + f5 INT AS (f1) VIRTUAL, INDEX(f4))ENGINE=InnoDB; +INSERT INTO t1(f1, f2, f3) VALUES(1, 2, 3); +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL dml_start WAIT_FOR dml_finish'; +send ALTER TABLE t1 ADD INDEX v1(f5, f2, f4), ADD INDEX v2(f3, f5); + +connection con1; +set DEBUG_SYNC="now WAIT_FOR dml_start"; +UPDATE t1 SET f3= f3 + 1; +set DEBUG_SYNC="now SIGNAL dml_finish"; + +disconnect con1; +connection default; +reap; +CHECK TABLE t1 EXTENDED; +SELECT f5, f2, f4 FROM t1 USE INDEX(v1); +SELECT f3, f5 FROM t1 USE INDEX(v2); +DROP TABLE t1; + SET DEBUG_SYNC = 'RESET'; # Check that all connections opened by test cases in this file are really diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 6f3425aab17e3..702e70988391f 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -4065,21 +4065,20 @@ void UndorecApplier::log_update(const dtuple_t &tuple, if (!(this->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { for (ulint i = 0; i < dict_table_get_n_v_cols(table); i++) - dfield_get_type( - dtuple_get_nth_v_field(row, i))->mtype = DATA_MISSING; + dfield_get_type(dtuple_get_nth_v_field(row, i))->mtype = DATA_MISSING; } + if (table->n_v_cols) + row_upd_replace_vcol(row, table, update, false, nullptr, + (cmpl_info & UPD_NODE_NO_ORD_CHANGE) + ? nullptr : undo_rec); + if (is_update) { old_row= dtuple_copy(row, heap); row_upd_replace(old_row, &old_ext, clust_index, update, heap); } - if (table->n_v_cols) - row_upd_replace_vcol(row, table, update, false, nullptr, - (cmpl_info & UPD_NODE_NO_ORD_CHANGE) - ? nullptr : undo_rec); - bool success= true; dict_index_t *index= dict_table_get_next_index(clust_index); while (index)