diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-07-02 08:56:23 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-07-26 15:55:58 +0300 |
commit | 0bd9f755b798718dab8e354d39238d5e1457fd39 (patch) | |
tree | 7eeb8789e9fc0b699bda7ce99641c227effc5131 | |
parent | ce870b2a2a54a1cab844be40a3fabdc8a2a53ce2 (diff) | |
download | mariadb-git-0bd9f755b798718dab8e354d39238d5e1457fd39.tar.gz |
MDEV-26062 : InnoDB: WSREP: referenced FK check fail: Lock wait index `PRIMARY` table `schema`.`child_table`
Problem was that not all normal error codes where not handled
after wsrep_row_upd_check_foreign_constraints() call. Furhermore,
debug assertion did not contain all normal error cases. Changed
ib:: calls to WSREP_ calls to use wsrep instrumentation.
-rw-r--r-- | mysql-test/suite/galera/r/galera_fk_lock_wait.result | 52 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_fk_lock_wait.test | 40 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 76 |
3 files changed, 133 insertions, 35 deletions
diff --git a/mysql-test/suite/galera/r/galera_fk_lock_wait.result b/mysql-test/suite/galera/r/galera_fk_lock_wait.result new file mode 100644 index 00000000000..7bbbf40cb29 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_fk_lock_wait.result @@ -0,0 +1,52 @@ +CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY, +parent_name varchar(80)) ENGINE=InnoDB; +CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY, +child_name varchar(80), +child_parent_id int not null, +CONSTRAINT `fk_child_parent` + FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id) +ON DELETE CASCADE +ON UPDATE CASCADE) ENGINE=InnoDB; +INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp'); +INSERT INTO child VALUES (NULL,'first_child',1); +INSERT INTO child VALUES (NULL,'second_child',1); +INSERT INTO child VALUES (NULL,'first_child2',2); +INSERT INTO child VALUES (NULL,'first_child3',2); +INSERT INTO child VALUES (NULL,'first_child4',3); +BEGIN; +UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION innodb_lock_wait_timeout=2; +UPDATE child SET child_parent_id = 5 where child_parent_id = 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +connection node_1; +COMMIT; +SELECT * FROM parent; +parent_id parent_name +1 first +2 bar +3 foo +4 tmp +SELECT * FROM child; +child_id child_name child_parent_id +1 first_child 1 +3 second_child 1 +5 first_child2 2 +7 first_child3 2 +9 first_child4 3 +connection node_2; +SELECT * FROM parent; +parent_id parent_name +1 first +2 bar +3 foo +4 tmp +SELECT * FROM child; +child_id child_name child_parent_id +1 first_child 1 +3 second_child 1 +5 first_child2 2 +7 first_child3 2 +9 first_child4 3 +DROP TABLE child, parent; +disconnect node_1a; diff --git a/mysql-test/suite/galera/t/galera_fk_lock_wait.test b/mysql-test/suite/galera/t/galera_fk_lock_wait.test new file mode 100644 index 00000000000..150c7397f7e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_fk_lock_wait.test @@ -0,0 +1,40 @@ +--source include/galera_cluster.inc + +CREATE TABLE parent(parent_id int not null AUTO_INCREMENT PRIMARY KEY, +parent_name varchar(80)) ENGINE=InnoDB; + +CREATE TABLE child(child_id int not null AUTO_INCREMENT PRIMARY KEY, +child_name varchar(80), +child_parent_id int not null, +CONSTRAINT `fk_child_parent` + FOREIGN KEY (child_parent_id) REFERENCES parent (parent_id) + ON DELETE CASCADE + ON UPDATE CASCADE) ENGINE=InnoDB; + +INSERT INTO parent VALUES (1, 'first'),(2,'second'),(3,'foo'),(4,'tmp'); +INSERT INTO child VALUES (NULL,'first_child',1); +INSERT INTO child VALUES (NULL,'second_child',1); +INSERT INTO child VALUES (NULL,'first_child2',2); +INSERT INTO child VALUES (NULL,'first_child3',2); +INSERT INTO child VALUES (NULL,'first_child4',3); + +BEGIN; +UPDATE parent SET parent_name = 'bar' WHERE parent_id = 2; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION innodb_lock_wait_timeout=2; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE child SET child_parent_id = 5 where child_parent_id = 2; + +--connection node_1 +COMMIT; +SELECT * FROM parent; +SELECT * FROM child; + +--connection node_2 + +SELECT * FROM parent; +SELECT * FROM child; +DROP TABLE child, parent; + +--disconnect node_1a diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 429282906df..1f3e34d493a 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -52,6 +52,11 @@ Created 12/27/1996 Heikki Tuuri #include <algorithm> #include <mysql/plugin.h> #include <mysql/service_wsrep.h> +#ifdef WITH_WSREP +#include "log.h" +#include "wsrep.h" +#endif /* WITH_WSREP */ + /* What kind of latch and lock can we assume when the control comes to ------------------------------------------------------------------- @@ -2461,34 +2466,30 @@ row_upd_sec_index_entry( err = DB_SUCCESS; break; case DB_LOCK_WAIT: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK lock wait" - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - } - break; case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); break; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name - << " query " << wsrep_thd_query(trx->mysql_thd); - + WSREP_ERROR("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); break; } } #endif /* WITH_WSREP */ } +#ifdef WITH_WSREP + ut_ad(err == DB_SUCCESS || err == DB_LOCK_WAIT + || err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT); +#else ut_ad(err == DB_SUCCESS); +#endif if (referenced) { @@ -2800,17 +2801,21 @@ check_fk: case DB_NO_REFERENCED_ROW: err = DB_SUCCESS; break; + case DB_LOCK_WAIT: case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name; - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); + goto err_exit; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name; + WSREP_ERROR("Foreign key check fail: " + "%s on table %s index %s query %s", + ut_strerr(err), index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); + goto err_exit; } #endif /* WITH_WSREP */ @@ -3027,18 +3032,19 @@ row_upd_del_mark_clust_rec( case DB_NO_REFERENCED_ROW: err = DB_SUCCESS; break; + case DB_LOCK_WAIT: case DB_DEADLOCK: - if (UNIV_UNLIKELY(wsrep_debug)) { - ib::warn() << "WSREP: sec index FK check fail for deadlock" - << " index " << index->name - << " table " << index->table->name; - } + case DB_LOCK_WAIT_TIMEOUT: + WSREP_DEBUG("Foreign key check fail: " + "%d on table %s index %s query %s", + err, index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); break; default: - ib::error() << "WSREP: referenced FK check fail: " << err - << " index " << index->name - << " table " << index->table->name; - + WSREP_ERROR("Foreign key check fail: " + "%d on table %s index %s query %s", + err, index->name, index->table->name, + wsrep_thd_query(trx->mysql_thd)); break; } #endif /* WITH_WSREP */ |