summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Sciascia <daniele.sciascia@galeracluster.com>2022-01-13 12:51:54 +0100
committerJan Lindström <jan.lindstrom@mariadb.com>2022-01-19 15:32:42 +0200
commitc75bee9478f4f2d458d3522a4bd496b95e118498 (patch)
treeda4a52616c73d10e4d8001b144247f53a75e0c8f
parentf8c3d5927445dcd75f31ed8e9fb3cfcc07c3ed8f (diff)
downloadmariadb-git-c75bee9478f4f2d458d3522a4bd496b95e118498.tar.gz
MDEV-25538 Crash on REPAIR VIEW that was created from IS tablebb-10.4-MDEV-25538
Remove calls to wsrep_append_fk_parent_table() during REPAIR/OPTIMIZE TABLE processing. It turns out that REPAIR or OPTIMIZE commands on table t, do not acquire MDL locks on parent tables of t (as shown in the included test). Thus making wsrep_append_fk_parent_table() unnecessary for OPTIMIZE and REPAIR. This also fixes MDEV-24446 and reenables test galera.mysql-wsrep#198. Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
-rw-r--r--mysql-test/suite/galera/disabled.def1
-rw-r--r--mysql-test/suite/galera/r/galera_ddl_fk_conflict.result383
-rw-r--r--mysql-test/suite/galera/r/galera_ddl_fk_no_conflict.result330
-rw-r--r--mysql-test/suite/galera/r/galera_repair_view.result17
-rw-r--r--mysql-test/suite/galera/t/galera_ddl_fk_conflict.test8
-rw-r--r--mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.inc34
-rw-r--r--mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.test57
-rw-r--r--mysql-test/suite/galera/t/galera_repair_view.test12
-rw-r--r--sql/sql_admin.cc62
9 files changed, 459 insertions, 445 deletions
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 96847510273..d6cbf1a2f7f 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -32,7 +32,6 @@ galera_var_ignore_apply_errors : MDEV-26770 galera_var_ignore_apply_errors fails
galera_var_node_address : MDEV-20485 Galera test failure
galera_var_notify_cmd : MDEV-21905 Galera test galera_var_notify_cmd causes hang
galera_var_retry_autocommit: MDEV-18181 Galera test failure on galera.galera_var_retry_autocommit
-mysql-wsrep#198 : MDEV-24446: galera.mysql-wsrep#198 MTR failed: query 'reap' failed: 2000: Unknown MySQL error
partition : MDEV-19958 Galera test failure on galera.partition
query_cache: MDEV-15805 Test failure on galera.query_cache
versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch
diff --git a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result
index 5f09345b79b..03e84f9facd 100644
--- a/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result
+++ b/mysql-test/suite/galera/r/galera_ddl_fk_conflict.result
@@ -7,389 +7,6 @@ connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1b;
SET SESSION wsrep_sync_wait=0;
######################################################################
-# Test for OPTIMIZE
-######################################################################
-######################################################################
-#
-# Scenario #1: DML working on FK parent table BF aborted by DDL
-# over child table
-#
-######################################################################
-connection node_1;
-SET SESSION wsrep_sync_wait=0;
-CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
-CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
-INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
-CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
-INSERT INTO c1 VALUES (1,1);
-CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
-INSERT INTO c2 VALUES (1,1,1), (2,1,2);
-connection node_1;
-SET AUTOCOMMIT=ON;
-START TRANSACTION;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-connection node_2;
-SET SESSION wsrep_sync_wait=0;
-OPTIMIZE TABLE c1 ;
-Table Op Msg_type Msg_text
-test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
-test.c1 optimize status OK
-connection node_1;
-COMMIT;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-######################################################################
-#
-# Scenario #2: DML working on FK parent table tries to replicate, but
-# fails in certification for earlier DDL on child table
-#
-######################################################################
-connection node_1;
-BEGIN;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-OPTIMIZE TABLE c1 ;
-Table Op Msg_type Msg_text
-test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
-test.c1 optimize status OK
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-######################################################################
-#
-# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
-# but fails in certification for earlier DDL on child table
-# which is child to both FK parents
-#
-######################################################################
-connection node_1;
-BEGIN;
-connection node_1b;
-BEGIN;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-OPTIMIZE TABLE c2 ;
-Table Op Msg_type Msg_text
-test.c2 optimize note Table does not support optimize, doing recreate + analyze instead
-test.c2 optimize status OK
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1b;
-UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-connection node_1b;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-DROP TABLE c1, c2;
-DROP TABLE p1, p2;
-######################################################################
-# Test for OPTIMIZE
-######################################################################
-connection node_1;
-SET SESSION wsrep_sync_wait=0;
-CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
-CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
-INSERT INTO c1 VALUES (1,1);
-######################################################################
-#
-# Scenario #4: DML working on FK parent table tries to replicate, but
-# fails in certification for earlier DDL on child table
-# and another temporary table. TMP table should be skipped
-# but FK child table should be replicated with proper keys
-#
-######################################################################
-connection node_1;
-BEGIN;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-CREATE TEMPORARY TABLE tmp (i int);
-OPTIMIZE TABLE c1, tmp ;
-Table Op Msg_type Msg_text
-test.c1 optimize note Table does not support optimize, doing recreate + analyze instead
-test.c1 optimize status OK
-test.tmp optimize note Table does not support optimize, doing recreate + analyze instead
-test.tmp optimize status OK
-DROP TABLE tmp;
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-DROP TABLE c1;
-DROP TABLE p1;
-######################################################################
-# Test for REPAIR
-######################################################################
-######################################################################
-#
-# Scenario #1: DML working on FK parent table BF aborted by DDL
-# over child table
-#
-######################################################################
-connection node_1;
-SET SESSION wsrep_sync_wait=0;
-CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
-CREATE TABLE p2 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p2 VALUES (1, 'INITIAL VALUE');
-INSERT INTO p2 VALUES (2, 'INITIAL VALUE');
-CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
-INSERT INTO c1 VALUES (1,1);
-CREATE TABLE c2 (pk INTEGER PRIMARY KEY, fk1 INTEGER, fk2 INTEGER, FOREIGN KEY (fk1) REFERENCES p1(pk), FOREIGN KEY (fk2) REFERENCES p2(pk));
-INSERT INTO c2 VALUES (1,1,1), (2,1,2);
-connection node_1;
-SET AUTOCOMMIT=ON;
-START TRANSACTION;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-connection node_2;
-SET SESSION wsrep_sync_wait=0;
-REPAIR TABLE c1 ;
-Table Op Msg_type Msg_text
-test.c1 repair note The storage engine for the table doesn't support repair
-connection node_1;
-COMMIT;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-######################################################################
-#
-# Scenario #2: DML working on FK parent table tries to replicate, but
-# fails in certification for earlier DDL on child table
-#
-######################################################################
-connection node_1;
-BEGIN;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-REPAIR TABLE c1 ;
-Table Op Msg_type Msg_text
-test.c1 repair note The storage engine for the table doesn't support repair
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-######################################################################
-#
-# Scenario #3: 2 DMLs working on two FK parent tables try to replicate,
-# but fails in certification for earlier DDL on child table
-# which is child to both FK parents
-#
-######################################################################
-connection node_1;
-BEGIN;
-connection node_1b;
-BEGIN;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-REPAIR TABLE c2 ;
-Table Op Msg_type Msg_text
-test.c2 repair note The storage engine for the table doesn't support repair
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1b;
-UPDATE p2 SET f2 = 'TO DEADLOCK' WHERE pk = 2;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-connection node_1b;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-SELECT COUNT(*) AS EXPECT_2 FROM p2 WHERE f2 = 'INITIAL VALUE';
-EXPECT_2
-2
-DROP TABLE c1, c2;
-DROP TABLE p1, p2;
-######################################################################
-# Test for REPAIR
-######################################################################
-connection node_1;
-SET SESSION wsrep_sync_wait=0;
-CREATE TABLE p1 (pk INTEGER PRIMARY KEY, f2 CHAR(30));
-INSERT INTO p1 VALUES (1, 'INITIAL VALUE');
-CREATE TABLE c1 (pk INTEGER PRIMARY KEY, fk INTEGER, FOREIGN KEY (fk) REFERENCES p1(pk));
-INSERT INTO c1 VALUES (1,1);
-######################################################################
-#
-# Scenario #4: DML working on FK parent table tries to replicate, but
-# fails in certification for earlier DDL on child table
-# and another temporary table. TMP table should be skipped
-# but FK child table should be replicated with proper keys
-#
-######################################################################
-connection node_1;
-BEGIN;
-SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
-connection node_2;
-CREATE TEMPORARY TABLE tmp (i int);
-REPAIR TABLE c1, tmp ;
-Table Op Msg_type Msg_text
-test.c1 repair note The storage engine for the table doesn't support repair
-test.tmp repair note The storage engine for the table doesn't support repair
-DROP TABLE tmp;
-connection node_1a;
-SET SESSION wsrep_on = 0;
-SET SESSION wsrep_on = 1;
-SET GLOBAL wsrep_provider_options = 'dbug=';
-connection node_1;
-UPDATE p1 SET f2 = 'TO DEADLOCK' WHERE pk = 1;
-COMMIT;
-connection node_1a;
-SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
-connection node_1;
-ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-SELECT 'I deadlocked';
-I deadlocked
-I deadlocked
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-connection node_2;
-SELECT COUNT(*) AS EXPECT_1 FROM p1 WHERE f2 = 'INITIAL VALUE';
-EXPECT_1
-1
-DROP TABLE c1;
-DROP TABLE p1;
-######################################################################
# Test for ALTER ENGINE=INNODB
######################################################################
######################################################################
diff --git a/mysql-test/suite/galera/r/galera_ddl_fk_no_conflict.result b/mysql-test/suite/galera/r/galera_ddl_fk_no_conflict.result
new file mode 100644
index 00000000000..43046922143
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_ddl_fk_no_conflict.result
@@ -0,0 +1,330 @@
+connection node_2;
+connection node_1;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) );
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+OPTIMIZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child optimize note Table does not support optimize, doing recreate + analyze instead
+test.child optimize status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+OPTIMIZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child optimize note Table does not support optimize, doing recreate + analyze instead
+test.child optimize status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+OPTIMIZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child optimize note Table does not support optimize, doing recreate + analyze instead
+test.child optimize status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+OPTIMIZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child optimize note Table does not support optimize, doing recreate + analyze instead
+test.child optimize status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) );
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+REPAIR TABLE child;;
+Table Op Msg_type Msg_text
+test.child repair note The storage engine for the table doesn't support repair
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+REPAIR TABLE child;;
+Table Op Msg_type Msg_text
+test.child repair note The storage engine for the table doesn't support repair
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+REPAIR TABLE child;;
+Table Op Msg_type Msg_text
+test.child repair note The storage engine for the table doesn't support repair
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+REPAIR TABLE child;;
+Table Op Msg_type Msg_text
+test.child repair note The storage engine for the table doesn't support repair
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) );
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+CHECK TABLE child;;
+Table Op Msg_type Msg_text
+test.child check status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+CHECK TABLE child;;
+Table Op Msg_type Msg_text
+test.child check status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+CHECK TABLE child;;
+Table Op Msg_type Msg_text
+test.child check status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+CHECK TABLE child;;
+Table Op Msg_type Msg_text
+test.child check status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) );
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+ANALYZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child analyze status Engine-independent statistics collected
+test.child analyze status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+ANALYZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child analyze status Engine-independent statistics collected
+test.child analyze status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+ANALYZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child analyze status Engine-independent statistics collected
+test.child analyze status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) ON UPDATE CASCADE ON DELETE CASCADE);
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+connection node_1;
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+pk
+1
+2
+3
+4
+connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+ANALYZE TABLE child;;
+Table Op Msg_type Msg_text
+test.child analyze status Engine-independent statistics collected
+test.child analyze status OK
+connection node_1;
+COMMIT;
+DROP TABLE child, parent;
+disconnect node_1a;
diff --git a/mysql-test/suite/galera/r/galera_repair_view.result b/mysql-test/suite/galera/r/galera_repair_view.result
new file mode 100644
index 00000000000..8dfe8c8db52
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_repair_view.result
@@ -0,0 +1,17 @@
+connection node_2;
+connection node_1;
+CREATE TABLE t1(a int not null primary key) engine=innodb;
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair note The storage engine for the table doesn't support repair
+CREATE VIEW v1 AS SELECT a FROM t1;
+REPAIR VIEW v1;
+Table Op Msg_type Msg_text
+test.v1 repair status OK
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE VIEW v1 AS SELECT table_name FROM information_schema.tables;
+REPAIR VIEW v1;
+Table Op Msg_type Msg_text
+test.v1 repair status OK
+DROP VIEW v1;
diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test
index 88837933e5a..4ec866a9f74 100644
--- a/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test
+++ b/mysql-test/suite/galera/t/galera_ddl_fk_conflict.test
@@ -17,14 +17,6 @@ SET SESSION wsrep_sync_wait=0;
--connection node_1b
SET SESSION wsrep_sync_wait=0;
---let $table_admin_command = OPTIMIZE
---source galera_ddl_fk_conflict.inc
---source galera_ddl_fk_conflict_with_tmp.inc
-
---let $table_admin_command = REPAIR
---source galera_ddl_fk_conflict.inc
---source galera_ddl_fk_conflict_with_tmp.inc
-
--let $table_admin_command = ALTER
--let $table_admin_command_end = ENGINE=INNODB
--source galera_ddl_fk_conflict.inc
diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.inc b/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.inc
new file mode 100644
index 00000000000..9e2dd391678
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.inc
@@ -0,0 +1,34 @@
+# This test attempts to show that OPTIMIZE on a child table does NOT
+# acquire MDL locks on the parent table. #
+# param: $table_admin_command
+# DDL table command to test, script will build full SQL statement:
+# $table_admin_command TABLE c;
+#
+# param: $FK_constraint
+# Foreign key constraint to use when creating the child table.
+#
+
+CREATE TABLE parent (pk INTEGER PRIMARY KEY);
+--eval CREATE TABLE child (pk INTEGER PRIMARY KEY, parent_id INTEGER, FOREIGN KEY(parent_id) REFERENCES parent(pk) $fk_constraint)
+
+INSERT INTO parent VALUES (1), (2), (3), (4);
+INSERT INTO child VALUES (1,1), (2,2), (3,3), (4,4);
+
+--connection node_1
+# Start a transaction that uses the parent table,
+# so that we acquire MDL lock on parent.
+START TRANSACTION;
+SELECT * FROM parent FOR UPDATE;
+
+# In a different connection, execute the table
+# admin command (OPTIMIZE / REPAIR ...) on the child table.
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+--eval $table_admin_command TABLE child;
+
+# Expect no conflict.
+--connection node_1
+COMMIT;
+
+DROP TABLE child, parent;
+
+--disconnect node_1a
diff --git a/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.test b/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.test
new file mode 100644
index 00000000000..6307b629e2b
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_ddl_fk_no_conflict.test
@@ -0,0 +1,57 @@
+#
+# This test attempts to show that table admin commands
+# (OPTIMIZE / REPAIR / ANALYZE ...) on child table,
+# do NOT cause conflicts on parent table operations.
+# Contrary to what is said in MDEV-21577, which claimed
+# that OPTIMIZE and REPAIR do take MDL locks on parent
+# table.
+#
+# Should this test start failing due to a conflict
+# (i.e. ER_LOCK_DEADLOCK), then it might be that we
+# are missing additional keys for certification
+# on the corresponding table admin command.
+
+--source include/galera_cluster.inc
+
+--let $table_admin_command = OPTIMIZE
+--let $fk_constraint =
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+
+
+--let $table_admin_command = REPAIR
+--let $fk_constraint =
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+
+
+--let $table_admin_command = CHECK
+--let $fk_constraint =
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+
+
+--let $table_admin_command = ANALYZE
+--let $fk_constraint =
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
+--let $fk_constraint = ON UPDATE CASCADE ON DELETE CASCADE
+--source galera_ddl_fk_no_conflict.inc
diff --git a/mysql-test/suite/galera/t/galera_repair_view.test b/mysql-test/suite/galera/t/galera_repair_view.test
new file mode 100644
index 00000000000..0010d90c7ec
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_repair_view.test
@@ -0,0 +1,12 @@
+--source include/galera_cluster.inc
+
+CREATE TABLE t1(a int not null primary key) engine=innodb;
+REPAIR TABLE t1;
+CREATE VIEW v1 AS SELECT a FROM t1;
+REPAIR VIEW v1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+CREATE VIEW v1 AS SELECT table_name FROM information_schema.tables;
+REPAIR VIEW v1;
+DROP VIEW v1;
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index f692afb1440..213d77f8237 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -436,49 +436,6 @@ dbug_err:
return open_error;
}
-#ifdef WITH_WSREP
- /*
- OPTIMIZE, REPAIR and ALTER may take MDL locks not only for the affected table, but
- also for the table referenced by foreign key constraint.
- This wsrep_toi_replication() function handles TOI replication for OPTIMIZE and REPAIR
- so that certification keys for potential FK parent tables are also appended in the
- write set.
- ALTER TABLE case is handled elsewhere.
- */
-static bool wsrep_toi_replication(THD *thd, TABLE_LIST *tables)
-{
- LEX *lex= thd->lex;
- /* only handle OPTIMIZE and REPAIR here */
- switch (lex->sql_command)
- {
- case SQLCOM_OPTIMIZE:
- case SQLCOM_REPAIR:
- break;
- default:
- return false;
- }
-
- close_thread_tables(thd);
- wsrep::key_array keys;
-
- wsrep_append_fk_parent_table(thd, tables, &keys);
-
- /* now TOI replication, with no locks held */
- if (keys.empty())
- {
- if (!thd->lex->no_write_to_binlog &&
- wsrep_to_isolation_begin(thd, NULL, NULL, tables))
- return true;
- }
- else
- {
- if (!thd->lex->no_write_to_binlog &&
- wsrep_to_isolation_begin(thd, NULL, NULL, tables, NULL, &keys))
- return true;
- }
- return false;
-}
-#endif /* WITH_WSREP */
/*
RETURN VALUES
@@ -550,16 +507,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
close_thread_tables(thd);
for (table= tables; table; table= table->next_local)
table->table= NULL;
-#ifdef WITH_WSREP
- if (WSREP(thd))
- {
- if(wsrep_toi_replication(thd, tables))
- {
- WSREP_INFO("wsrep TOI replication of has failed.");
- goto err;
- }
- }
-#endif /* WITH_WSREP */
for (table= tables; table; table= table->next_local)
{
@@ -1468,6 +1415,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
FALSE, UINT_MAX, FALSE))
goto error; /* purecov: inspected */
+ WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
res= (specialflag & SPECIAL_NO_NEW_FUNC) ?
mysql_recreate_table(thd, first_table, true) :
mysql_admin_table(thd, first_table, &m_lex->check_opt,
@@ -1477,6 +1425,9 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
+#ifdef WITH_WSREP
+wsrep_error_label:
+#endif /* WITH_WSREP */
error:
DBUG_RETURN(res);
}
@@ -1492,6 +1443,8 @@ bool Sql_cmd_repair_table::execute(THD *thd)
if (check_table_access(thd, SELECT_ACL | INSERT_ACL, first_table,
FALSE, UINT_MAX, FALSE))
goto error; /* purecov: inspected */
+
+ WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
res= mysql_admin_table(thd, first_table, &m_lex->check_opt, "repair",
TL_WRITE, 1,
MY_TEST(m_lex->check_opt.sql_flags & TT_USEFRM),
@@ -1501,6 +1454,9 @@ bool Sql_cmd_repair_table::execute(THD *thd)
m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
+#ifdef WITH_WSREP
+wsrep_error_label:
+#endif /* WITH_WSREP */
error:
DBUG_RETURN(res);
}