summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-12-03 16:47:13 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-12-04 23:26:41 +0300
commit149a9bd5262f979dd71185b2afe0d828b8577822 (patch)
tree4028ea61a1f24fbb5d6f6f4f64c0d5e354137cee
parent2362e6c0e261882c8249206f3dd8bb3ee263bc9e (diff)
downloadmariadb-git-149a9bd5262f979dd71185b2afe0d828b8577822.tar.gz
write_shadow_frms()
-rw-r--r--mysql-test/suite/innodb/r/f.result492
-rw-r--r--mysql-test/suite/innodb/t/f.test18
-rw-r--r--sql/datadict.cc58
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_rename.cc12
-rw-r--r--sql/sql_table.cc34
-rw-r--r--storage/innobase/handler/ha_innodb.cc11
8 files changed, 586 insertions, 45 deletions
diff --git a/mysql-test/suite/innodb/r/f.result b/mysql-test/suite/innodb/r/f.result
index b7fdfafb447..ff5ee162db5 100644
--- a/mysql-test/suite/innodb/r/f.result
+++ b/mysql-test/suite/innodb/r/f.result
@@ -68,6 +68,84 @@ test.t3 check Note Found 1 self-references
test.t3 check status OK
test.t4 check Note Found 3 foreign keys
test.t4 check status OK
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+drop tables t4, t1, t3, t2;
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
set @@debug_dbug= "+d,fail_fk_backup_frm";
drop tables t4, t1, t3, t2;
ERROR HY000: Unknown error
@@ -400,6 +478,102 @@ test.t2 check status OK
test.t3 check status OK
test.t4 check Error Table 'test.t4' doesn't exist
test.t4 check status Operation failed
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+create table t4 (a int primary key, x int references t1(x), y int references t2(y), z int references t3(z));
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
+set @@debug_dbug= "+d,fail_fk_backup_frm";
+create table t4 (a int primary key, x int references t1(x), y int references t2(y), z int references t3(z));
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+test.t4 check Error Table 'test.t4' doesn't exist
+test.t4 check status Operation failed
set @@debug_dbug= "+d,fail_fk_backup_frm";
create table t4 (a int primary key, x int references t1(x), y int references t2(y), z int references t3(z));
ERROR HY000: Unknown error
@@ -649,6 +823,84 @@ test.t3 check Note Found 1 self-references
test.t3 check status OK
test.t4 check Note Found 3 foreign keys
test.t4 check status OK
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+rename table t4 to xt4, t1 to xt1, t3 to xt3, t2 to xt2;
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
set @@debug_dbug= "+d,fail_fk_backup_frm";
rename table t4 to xt4, t1 to xt1, t3 to xt3, t2 to xt2;
ERROR HY000: Unknown error
@@ -805,6 +1057,84 @@ test.t3 check Note Found 1 self-references
test.t3 check status OK
test.t4 check Note Found 3 foreign keys
test.t4 check status OK
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+alter table t3 rename xt3;
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
set @@debug_dbug= "+d,fail_fk_backup_frm";
alter table t3 rename xt3;
ERROR HY000: Unknown error
@@ -964,6 +1294,84 @@ test.t3 check Note Found 1 self-references
test.t3 check status OK
test.t4 check Note Found 3 foreign keys
test.t4 check status OK
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+alter table t2 change y z int, change x y int, change b c int;
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
set @@debug_dbug= "+d,fail_fk_backup_frm";
alter table t2 change y z int, change x y int, change b c int;
ERROR HY000: Unknown error
@@ -1294,6 +1702,90 @@ test.t3 check Note Found 1 self-references
test.t3 check status OK
test.t4 check Note Found 3 foreign keys
test.t4 check status OK
+set @@debug_dbug= "+d,fail_fk_write_shadow_frm";
+alter table t3
+drop foreign key fk_t3,
+drop foreign key fk_t3_2,
+drop foreign key fk_t3_3,
+drop c,
+add foreign key (x) references t1(x),
+add foreign key (y) references t2(x);
+ERROR HY000: Unknown error
+# State after failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+set session debug_dbug=@save_dbug;
+set @save_dbug=@@debug_dbug;
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
+# State before failure
+db.opt
+t1.MYD
+t1.MYI
+t1.frm
+t2.MYD
+t2.MYI
+t2.frm
+t3.MYD
+t3.MYI
+t3.frm
+t4.MYD
+t4.MYI
+t4.frm
+check tables t1, t2, t3, t4;
+Table Op Msg_type Msg_text
+test.t1 check Note Found 2 referenced keys
+test.t1 check Note Found 1 self-references
+test.t1 check status OK
+test.t2 check Note Found 3 referenced keys
+test.t2 check Note Found 1 foreign keys
+test.t2 check Note Found 1 self-references
+test.t2 check status OK
+test.t3 check Note Found 1 referenced keys
+test.t3 check Note Found 2 foreign keys
+test.t3 check Note Found 1 self-references
+test.t3 check status OK
+test.t4 check Note Found 3 foreign keys
+test.t4 check status OK
set @@debug_dbug= "+d,fail_fk_backup_frm";
alter table t3
drop foreign key fk_t3,
diff --git a/mysql-test/suite/innodb/t/f.test b/mysql-test/suite/innodb/t/f.test
index 000d8ce342e..f4601406fae 100644
--- a/mysql-test/suite/innodb/t/f.test
+++ b/mysql-test/suite/innodb/t/f.test
@@ -44,8 +44,10 @@ let $show_statement2= check tables t1, t2, t3, t4;
call make_tables;
--let $crash_statement=
--let $create_statement=
-let $debug_dbug="+d,fail_fk_backup_frm";
let $fail_statement= drop tables t4, t1, t3, t2;
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
+let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
--source include/foreign_fail.inc
@@ -56,7 +58,7 @@ let $debug_dbug="+d,crash_fk_install_shadow_frm";
--source include/foreign_fail.inc
call drop_tables;
-# FIXME: crash statements, fail_fk_write_shadow
+# FIXME: crash statements
--echo # CREATE TABLE
create table t1 (x int primary key);
@@ -65,6 +67,10 @@ create table t3 (z int primary key);
--let $create_statement=
--let $crash_statement=
let $fail_statement= create table t4 (a int primary key, x int references t1(x), y int references t2(y), z int references t3(z));
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
+let $debug_dbug="+d,fail_fk_backup_frm";
+--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
@@ -82,6 +88,8 @@ call make_tables;
--let $create_statement=
--let $crash_statement=
let $fail_statement= rename table t4 to xt4, t1 to xt1, t3 to xt3, t2 to xt2;
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
@@ -95,6 +103,8 @@ let $debug_dbug="+d,fail_fk_install_shadow_frm";
--let $crash_statement=
let $show_statement2= $show_statement0;
let $fail_statement= alter table t3 rename xt3;
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
@@ -111,6 +121,8 @@ call make_tables;
--let $create_statement=
--let $crash_statement=
let $fail_statement= alter table t2 change y z int, change x y int, change b c int;
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
@@ -133,6 +145,8 @@ let $fail_statement= alter table t3
drop c,
add foreign key (x) references t1(x),
add foreign key (y) references t2(x);
+let $debug_dbug="+d,fail_fk_write_shadow_frm";
+--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_backup_frm";
--source include/foreign_fail.inc
let $debug_dbug="+d,fail_fk_install_shadow_frm";
diff --git a/sql/datadict.cc b/sql/datadict.cc
index 07f67d25fd0..9369371f559 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -520,6 +520,7 @@ int FK_backup::fk_write_shadow_frm(ddl_log_info &log_info)
{
char shadow_path[FN_REFLEN + 1];
char frm_name[FN_REFLEN + 1];
+ int err;
TABLE_SHARE *s= get_share();
DBUG_ASSERT(s);
build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1,
@@ -528,9 +529,30 @@ int FK_backup::fk_write_shadow_frm(ddl_log_info &log_info)
if (log_info.write_log_replace_delete_file(NULL, frm_name, false))
return true;
delete_shadow_entry= log_info.first_entry;
- int err= s->fk_write_shadow_frm_impl(shadow_path);
- if (ERROR_INJECT("fail_fk_write_shadow", "crash_fk_write_shadow"))
- return true;
+#ifndef DBUG_OFF
+ if (log_info.dbg_fail &&
+ (ERROR_INJECT("fail_fk_write_shadow_frm", "crash_fk_write_shadow_frm")))
+ {
+ err= 10;
+ goto write_shadow_failed;
+ }
+#endif
+ err= s->fk_write_shadow_frm_impl(shadow_path);
+ if (err)
+ {
+#ifndef DBUG_OFF
+write_shadow_failed:
+#endif
+ if (deactivate_ddl_log_entry(delete_shadow_entry->entry_pos))
+ {
+ /* This is very bad case because log replay will delete original frm.
+ At least try prohibit replaying it and push an alert message. */
+ log_info.write_log_finish();
+ my_printf_error(ER_DDL_LOG_ERROR, "Deactivating delete shadow entry %u failed",
+ MYF(0), delete_shadow_entry->entry_pos);
+ }
+ delete_shadow_entry= NULL;
+ }
return err;
}
@@ -644,7 +666,35 @@ void FK_backup::fk_drop_backup_frm(ddl_log_info &log_info)
}
-bool FK_ddl_vector::install_shadow_frms(THD *thd)
+int FK_ddl_vector::write_shadow_frms()
+{
+ int err;
+#ifndef DBUG_OFF
+ FK_backup *last;
+ for (auto &bak: *this)
+ {
+ if (!bak.second.update_frm)
+ continue;
+ last= &bak.second;
+ }
+ dbg_fail= false;
+#endif
+ for (auto &bak: *this)
+ {
+ if (!bak.second.update_frm)
+ continue;
+#ifndef DBUG_OFF
+ if (&bak.second == last)
+ dbg_fail= true;
+#endif
+ if ((err= bak.second.fk_write_shadow_frm(*this)))
+ return err;
+ }
+ return 0;
+}
+
+
+bool FK_ddl_vector::install_shadow_frms()
{
if (!size())
return false;
diff --git a/sql/handler.cc b/sql/handler.cc
index 1a35251871d..6555b992fd5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -5541,7 +5541,8 @@ int ha_create_table(THD *thd, const char *path,
if (fk_update_refs &&
(share.fk_handle_create(thd, fk_shares) ||
- fk_shares.install_shadow_frms(thd)))
+ fk_shares.write_shadow_frms() ||
+ fk_shares.install_shadow_frms()))
goto err;
share.m_psi= PSI_CALL_get_table_share(temp_table, &share);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 913413e80a8..b98f13700f5 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1068,7 +1068,8 @@ public:
class FK_ddl_vector: public mbd::map<TABLE_SHARE *, FK_ddl_backup>, public ddl_log_info
{
public:
- bool install_shadow_frms(THD *thd);
+ int write_shadow_frms();
+ bool install_shadow_frms();
void drop_backup_frms(THD *thd);
void rollback(THD *thd);
};
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 3664ccd217a..184c00fad62 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -162,17 +162,9 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent,
error= true;
else
{
- for (auto &ref: fk_rename_backup)
- {
- if (ref.second.fk_write_shadow_frm(fk_rename_backup))
- {
- error= true;
- break;
- }
- }
-
+ error= fk_rename_backup.write_shadow_frms();
if (!error)
- error= fk_rename_backup.install_shadow_frms(thd);
+ error= fk_rename_backup.install_shadow_frms();
}
/*
An exclusive lock on table names is satisfactory to ensure
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9587c09bd35..77c2e1dd968 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2547,7 +2547,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
table_name.str, MDL_EXCLUSIVE));
- error= shares.install_shadow_frms(thd);
+ error= shares.install_shadow_frms();
if (unlikely(error))
{
shares.rollback(thd);
@@ -8277,7 +8277,7 @@ static bool mysql_inplace_alter_table(THD *thd,
table_list->table= table= NULL;
// FIXME: do right after fk_handle_alter?
- if (alter_ctx->fk_ref_backup.install_shadow_frms(thd))
+ if (alter_ctx->fk_ref_backup.install_shadow_frms())
{
alter_ctx->fk_ref_backup.rollback(thd);
DBUG_RETURN(true);
@@ -10007,19 +10007,17 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list,
&alter_ctx->new_name, fk_rename_backup))
DBUG_RETURN(true);
- for (auto &ref: fk_rename_backup)
+
+ if (fk_rename_backup.write_shadow_frms())
{
- if (ref.second.fk_write_shadow_frm(fk_rename_backup))
- {
- fk_rename_backup.rollback(thd);
- DBUG_RETURN(true);
- }
+ fk_rename_backup.rollback(thd);
+ DBUG_RETURN(true);
}
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME,
NULL);
- if (fk_rename_backup.install_shadow_frms(thd))
+ if (fk_rename_backup.install_shadow_frms())
{
fk_rename_backup.rollback(thd);
DBUG_RETURN(true);
@@ -11347,7 +11345,7 @@ err_rename_back:
}
}
- if (alter_ctx.fk_ref_backup.install_shadow_frms(thd))
+ if (alter_ctx.fk_ref_backup.install_shadow_frms())
goto err_rename_back;
if (alter_ctx.is_table_renamed())
@@ -12574,9 +12572,6 @@ bool TABLE_SHARE::fk_handle_create(THD *thd, FK_ddl_vector &shares, FK_list *fk_
return true;
}
} // for (const FK_info &fk: fkeys)
-
- if (ref.second.fk_write_shadow_frm(shares))
- return true;
} // for (ref_tables)
return false;
@@ -12980,12 +12975,8 @@ bool Alter_table_ctx::fk_handle_alter(THD *thd)
} // for (const Table_name &ref: rk_renamed_table)
/* Update EXTRA2_FOREIGN_KEY_INFO section in FRM files. */
- for (auto &key_val: fk_ref_backup)
- {
- FK_share_backup *ref_bak= &key_val.second;
- if (ref_bak->update_frm && ref_bak->fk_write_shadow_frm(fk_ref_backup))
- return true;
- }
+ if (fk_ref_backup.write_shadow_frms())
+ return true;
if (ERROR_INJECT("fail_fk_alter_3", "crash_fk_alter_3"))
return true;
@@ -13144,6 +13135,11 @@ bool fk_handle_drop(THD *thd, TABLE_LIST *table, FK_ddl_vector &shares,
ref_it.remove();
}
}
+
+#ifndef DBUG_OFF
+ shares.dbg_fail= true;
+#endif
+
int err= ref->second.fk_write_shadow_frm(shares);
if (err)
{
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 2c8e091fc43..e65c6b44a9e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -21531,14 +21531,9 @@ fk_upgrade_legacy_storage(dict_table_t* table, trx_t* trx, THD *thd, TABLE_SHARE
share_backup->update_frm= true;
}
- // Update foreign FRM
- if (share_backup->fk_write_shadow_frm(ref_shares)) {
- err = DB_ERROR;
- goto rollback;
- }
-
- // Update referenced FRMs
- if (ref_shares.install_shadow_frms(thd)) {
+ // Update foreign and referenced FRMs
+ if (ref_shares.write_shadow_frms() ||
+ ref_shares.install_shadow_frms()) {
err = DB_ERROR;
goto rollback;
}