Skip to content

Commit

Permalink
MDEV-26062 : InnoDB: WSREP: referenced FK check fail: Lock wait index…
Browse files Browse the repository at this point in the history
… `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.
  • Loading branch information
Jan Lindström committed Jul 26, 2021
1 parent ce870b2 commit 0bd9f75
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 35 deletions.
52 changes: 52 additions & 0 deletions mysql-test/suite/galera/r/galera_fk_lock_wait.result
Original file line number Diff line number Diff line change
@@ -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;
40 changes: 40 additions & 0 deletions mysql-test/suite/galera/t/galera_fk_lock_wait.test
Original file line number Diff line number Diff line change
@@ -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
76 changes: 41 additions & 35 deletions storage/innobase/row/row0upd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------------------------------------------------
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -2800,17 +2801,21 @@ row_upd_clust_rec_by_insert(
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 */
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 0bd9f75

Please sign in to comment.