Browse Source

MDEV-13708 Crash with indexed virtual columns and FK cascading deletes

InnoDB was too eager to forget the open table (m_mysql_table=NULL)
and that caused it to try to open a table which was opened by the user
not FK-prelocked. The server didn't expect that.

After fixing this, it crashed in gcol.innodb_virtual_fk test, trying to
compute virtual columns for a table that didn't have them. Because
row_upd_store_row() was deleting a row from node->table, while computing
virtual columns in thr->prebuilt->m_mysql_table. Which wasn't necessarily
the same table, and might've not even had virtual columns, even if
node->table did.
pull/451/head
Sergei Golubchik 8 years ago
parent
commit
50a8beedfe
  1. 12
      mysql-test/suite/vcol/r/innodb_virtual_fk.result
  2. 16
      mysql-test/suite/vcol/t/innodb_virtual_fk.test
  3. 1
      storage/innobase/row/row0mysql.cc
  4. 3
      storage/innobase/row/row0upd.cc

12
mysql-test/suite/vcol/r/innodb_virtual_fk.result

@ -0,0 +1,12 @@
set default_storage_engine=innodb;
create table t1 (id int primary key, id2 int as (id) virtual, key id2 (id2));
create table t2 (id int key, constraint fk_id foreign key (id) references t1 (id) on delete cascade);
insert into t1 (id) values (1), (2);
insert into t2 (id) values (1), (2);
delete from t1;
select * from t1;
id id2
select * from t2;
id
drop table t2;
drop table t1;

16
mysql-test/suite/vcol/t/innodb_virtual_fk.test

@ -0,0 +1,16 @@
source include/have_innodb.inc;
set default_storage_engine=innodb;
#
# MDEV-13708 Crash with indexed virtual columns and FK cascading deletes
#
create table t1 (id int primary key, id2 int as (id) virtual, key id2 (id2));
create table t2 (id int key, constraint fk_id foreign key (id) references t1 (id) on delete cascade);
insert into t1 (id) values (1), (2);
insert into t2 (id) values (1), (2);
delete from t1;
select * from t1;
select * from t2;
drop table t2;
drop table t1;

1
storage/innobase/row/row0mysql.cc

@ -2029,7 +2029,6 @@ run_again:
node->cascade_upd_nodes = cascade_upd_nodes;
cascade_upd_nodes->pop_front();
thr->fk_cascade_depth++;
prebuilt->m_mysql_table = NULL;
goto run_again;
}

3
storage/innobase/row/row0upd.cc

@ -2966,7 +2966,8 @@ row_upd_del_mark_clust_rec(
entries */
row_upd_store_row(node, trx->mysql_thd,
thr->prebuilt ? thr->prebuilt->m_mysql_table : NULL);
thr->prebuilt && thr->prebuilt->table == node->table
? thr->prebuilt->m_mysql_table : NULL);
/* Mark the clustered index record deleted; we do not have to check
locks, because we assume that we have an x-lock on the record */

Loading…
Cancel
Save