具有多个触发器的 mysqldump
mysqldump with multiple triggers
我正在使用 mysqldump 创建备份并将其恢复到另一台服务器上。
我在这个数据库上经常使用的功能之一是触发器。看起来,如果对数据库的任何一个操作有多个触发器,则恢复失败是因为对尚未创建的对象(第二个触发器)的依赖。
原因似乎是两个触发器声明都包含对彼此的引用。但是当它们按顺序执行时,第一个失败。
CREATE TRIGGER trigger_one
...
PRECEDES trigger_two
...;
[and then a bit further down]
CREATE TRIGGER trigger_two
...
FOLLOWS trigger_one
...;
我在 Percona 博客 this article 之后将数据和结构分开,并将结构分开为 'just triggers' 和 'everything but',但问题仍然存在,我想成为能够自动备份和复制。
我无法重现问题。
我不太清楚Percona文章中提到的MySQL版本,但我怀疑是5.7(或至少5.7.2)。
测试:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.13 |
+-----------+
1 row in set (0.00 sec)
mysql> CREATE TABLE `mytable` (`mycol` BOOL);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TRIGGER `trigger_one` BEFORE INSERT ON `mytable`
-> FOR EACH ROW
-> SET NEW.`mycol` := 1;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TRIGGER `trigger_two` BEFORE INSERT ON `mytable`
-> FOR EACH ROW PRECEDES `trigger_one`
-> SET NEW.`mycol` := 2;
Query OK, 0 rows affected (0.00 sec)
$ mysqldump mydatabase > dump.sql
--
-- Table structure for table `mytable`
--
DROP TABLE IF EXISTS `mytable`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mytable` (
`mycol` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
...
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`testuser`@`testmachine`*/
/*!50003 TRIGGER `trigger_two` BEFORE INSERT ON `mytable`
FOR EACH ROW SET NEW.`mycol` := 2 */;;
DELIMITER ;
...
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`testuser`@`testmachine`*/
/*!50003 TRIGGER `trigger_one` BEFORE INSERT ON `mytable`
FOR EACH ROW
SET NEW.`mycol` := 1 */;;
DELIMITER ;
...
21.3.1 Trigger Syntax and Examples
...
... To affect trigger order, specify a clause after FOR EACH ROW that
indicates FOLLOWS or PRECEDES and the name of an existing trigger that
also has the same trigger event and action time. ...
...
我正在使用 mysqldump 创建备份并将其恢复到另一台服务器上。
我在这个数据库上经常使用的功能之一是触发器。看起来,如果对数据库的任何一个操作有多个触发器,则恢复失败是因为对尚未创建的对象(第二个触发器)的依赖。
原因似乎是两个触发器声明都包含对彼此的引用。但是当它们按顺序执行时,第一个失败。
CREATE TRIGGER trigger_one
...
PRECEDES trigger_two
...;
[and then a bit further down]
CREATE TRIGGER trigger_two
...
FOLLOWS trigger_one
...;
我在 Percona 博客 this article 之后将数据和结构分开,并将结构分开为 'just triggers' 和 'everything but',但问题仍然存在,我想成为能够自动备份和复制。
我无法重现问题。
我不太清楚Percona文章中提到的MySQL版本,但我怀疑是5.7(或至少5.7.2)。
测试:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.13 |
+-----------+
1 row in set (0.00 sec)
mysql> CREATE TABLE `mytable` (`mycol` BOOL);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TRIGGER `trigger_one` BEFORE INSERT ON `mytable`
-> FOR EACH ROW
-> SET NEW.`mycol` := 1;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TRIGGER `trigger_two` BEFORE INSERT ON `mytable`
-> FOR EACH ROW PRECEDES `trigger_one`
-> SET NEW.`mycol` := 2;
Query OK, 0 rows affected (0.00 sec)
$ mysqldump mydatabase > dump.sql
--
-- Table structure for table `mytable`
--
DROP TABLE IF EXISTS `mytable`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mytable` (
`mycol` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
...
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`testuser`@`testmachine`*/
/*!50003 TRIGGER `trigger_two` BEFORE INSERT ON `mytable`
FOR EACH ROW SET NEW.`mycol` := 2 */;;
DELIMITER ;
...
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`testuser`@`testmachine`*/
/*!50003 TRIGGER `trigger_one` BEFORE INSERT ON `mytable`
FOR EACH ROW
SET NEW.`mycol` := 1 */;;
DELIMITER ;
...
21.3.1 Trigger Syntax and Examples
...
... To affect trigger order, specify a clause after FOR EACH ROW that indicates FOLLOWS or PRECEDES and the name of an existing trigger that also has the same trigger event and action time. ...
...