summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result10
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test13
-rw-r--r--mysql-test/suite/rpl/include/rpl_parallel_show_binlog_events_purge_logs.inc1
-rw-r--r--storage/innobase/dict/dict0mem.cc46
-rw-r--r--storage/innobase/handler/ha_innodb.cc25
-rw-r--r--storage/innobase/include/trx0trx.h1
-rw-r--r--storage/innobase/trx/trx0roll.cc3
-rw-r--r--storage/innobase/trx/trx0trx.cc6
8 files changed, 88 insertions, 17 deletions
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index 1e145ab1aee..388164b33dc 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -279,6 +279,16 @@ ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES tx(x);
ALTER TABLE t1 DROP KEY idx;
ALTER TABLE t1 CHANGE a c INT;
DROP TABLE t1;
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
+ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
+ALTER TABLE t1 ADD COLUMN f INT;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (f1);
+SET FOREIGN_KEY_CHECKS= ON;
+ALTER TABLE t1 DROP f3;
+ALTER TABLE t1 CHANGE f f3 INT;
+DROP TABLE t1;
SET FOREIGN_KEY_CHECKS=1;
# Start of 10.2 tests
#
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index b5a84756914..13203383188 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -266,6 +266,19 @@ ALTER TABLE t1 DROP KEY idx;
ALTER TABLE t1 CHANGE a c INT;
# Cleanup
DROP TABLE t1;
+
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
+ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
+ALTER TABLE t1 ADD COLUMN f INT;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (f1);
+SET FOREIGN_KEY_CHECKS= ON;
+ALTER TABLE t1 DROP f3;
+ALTER TABLE t1 CHANGE f f3 INT;
+# Cleanup
+DROP TABLE t1;
+
SET FOREIGN_KEY_CHECKS=1;
--echo # Start of 10.2 tests
diff --git a/mysql-test/suite/rpl/include/rpl_parallel_show_binlog_events_purge_logs.inc b/mysql-test/suite/rpl/include/rpl_parallel_show_binlog_events_purge_logs.inc
index 7801498adb4..cddc9286bd2 100644
--- a/mysql-test/suite/rpl/include/rpl_parallel_show_binlog_events_purge_logs.inc
+++ b/mysql-test/suite/rpl/include/rpl_parallel_show_binlog_events_purge_logs.inc
@@ -15,6 +15,7 @@
# that with the fix local variable linfo is valid along all
# mysql_show_binlog_events function scope.
#
+--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/master-slave.inc
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index c44ddc72629..8c28892b234 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -592,17 +592,15 @@ dict_mem_table_col_rename_low(
}
}
- dict_index_t* new_index = dict_foreign_find_index(
+ /* New index can be null if InnoDB already dropped
+ the foreign index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
- /* New index can be null if InnoDB already dropped
- the foreign index when FOREIGN_KEY_CHECKS is
- disabled */
- foreign->foreign_index = new_index;
-
} else {
for (unsigned f = 0; f < foreign->n_fields; f++) {
@@ -624,7 +622,41 @@ dict_mem_table_col_rename_low(
foreign = *it;
- ut_ad(foreign->referenced_index != NULL);
+ if (!foreign->referenced_index) {
+ /* Referenced index could have been dropped
+ when foreign_key_checks is disabled. In that case,
+ rename the corresponding referenced_col_names and
+ find the equivalent referenced index also */
+ for (unsigned f = 0; f < foreign->n_fields; f++) {
+
+ const char*& rc =
+ foreign->referenced_col_names[f];
+ if (strcmp(rc, from)) {
+ continue;
+ }
+
+ if (to_len <= strlen(rc)) {
+ memcpy(const_cast<char*>(rc), to,
+ to_len + 1);
+ } else {
+ rc = static_cast<char*>(
+ mem_heap_dup(
+ foreign->heap,
+ to, to_len + 1));
+ }
+ }
+
+ /* New index can be null if InnoDB already dropped
+ the referenced index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->referenced_index = dict_foreign_find_index(
+ foreign->referenced_table, NULL,
+ foreign->referenced_col_names,
+ foreign->n_fields, NULL, true, false,
+ NULL, NULL, NULL);
+ return;
+ }
+
for (unsigned f = 0; f < foreign->n_fields; f++) {
/* foreign->referenced_col_names[] need to be
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 90cdbede0c1..7d93f2915c6 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4364,26 +4364,34 @@ innobase_commit_low(
{
#ifdef WITH_WSREP
const char* tmp = 0;
- if (trx->is_wsrep()) {
+ const bool is_wsrep = trx->is_wsrep();
+ THD* thd = trx->mysql_thd;
+ if (is_wsrep) {
#ifdef WSREP_PROC_INFO
char info[64];
info[sizeof(info) - 1] = '\0';
snprintf(info, sizeof(info) - 1,
"innobase_commit_low():trx_commit_for_mysql(%lld)",
- (long long) wsrep_thd_trx_seqno(trx->mysql_thd));
- tmp = thd_proc_info(trx->mysql_thd, info);
+ (long long) wsrep_thd_trx_seqno(thd));
+ tmp = thd_proc_info(thd, info);
#else
- tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
+ tmp = thd_proc_info(thd, "innobase_commit_low()");
#endif /* WSREP_PROC_INFO */
}
#endif /* WITH_WSREP */
if (trx_is_started(trx)) {
-
trx_commit_for_mysql(trx);
+ } else {
+ trx->will_lock = 0;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif /* WITH_WSREP */
}
- trx->will_lock = 0;
+
#ifdef WITH_WSREP
- if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); }
+ if (is_wsrep) {
+ thd_proc_info(thd, tmp);
+ }
#endif /* WITH_WSREP */
}
@@ -4730,6 +4738,9 @@ innobase_rollback_trx(
if (!trx->has_logged()) {
trx->will_lock = 0;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
DBUG_RETURN(0);
}
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 2ee565a4819..feb27e56115 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -454,6 +454,7 @@ Check transaction state */
ut_ad(!(t)->id); \
ut_ad(!(t)->has_logged()); \
ut_ad(!(t)->is_referenced()); \
+ ut_ad(!(t)->is_wsrep()); \
ut_ad(!(t)->read_view.is_open()); \
ut_ad((t)->lock.wait_thr == NULL); \
ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 87183174992..c06e181a097 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -227,6 +227,9 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
case TRX_STATE_NOT_STARTED:
trx->will_lock = 0;
ut_ad(trx->mysql_thd);
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
return(DB_SUCCESS);
case TRX_STATE_ACTIVE:
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 8e561399bbc..3d551f28e33 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -109,9 +109,6 @@ trx_init(
trx->state = TRX_STATE_NOT_STARTED;
trx->is_recovered = false;
-#ifdef WITH_WSREP
- trx->wsrep = false;
-#endif /* WITH_WSREP */
trx->op_info = "";
@@ -1484,6 +1481,9 @@ trx_commit_in_memory(
DBUG_LOG("trx", "Commit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED;
+#ifdef WITH_WSREP
+ trx->wsrep = false;
+#endif
assert_trx_is_free(trx);