summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-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
5 files changed, 75 insertions, 35 deletions
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)
{