2016-06-29 31 views
1

我正在使用mysqldump创建备份并将其恢复到另一台服务器上。带多个触发器的mysqldump

我在这个数据库上使用了很多功能之一就是触发器。看起来,如果数据库上的任何一个操作都有多个触发器,则由于依赖于尚未创建的对象(第二个触发器),还原失败。

原因似乎是两个触发器声明都包含对彼此的引用。但是,当它们按顺序执行时,第一个失败。

CREATE TRIGGER trigger_one 
... 
PRECEDES trigger_two 
...; 

[and then a bit further down] 

CREATE TRIGGER trigger_two 
... 
FOLLOWS trigger_one 
...; 

我已经分离数据和结构,还分离结构“只是触发”和“一切,但”在Percona的博客以下this article,但问题的存在,我想能够自动执行备份和复制。

+0

使用的每台服务器上的MySQL版本?你能显示错误信息吗? – wchiquito

+0

5.7.13在两台服务器上。 – Hans

回答

1

我无法重现该问题。

我没有非常清楚在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

...

...要影响的触发顺序,后指定一个子句每一行 表示跟随或前导和现有触发器的名称即 也具有相同的触发事件和动作时间。 ...

...

+0

Percona引用5.5。我完全可以做你正在做的事情。我遇到的问题是,当我运行'mysqldump --no-create-info --skip-triggers sakila> data.sql'两个触发器定义中的第一个包含'PRECEDES trigger_one'时,我通过My​​SQL工作台但会尝试使用命令行 - 我认为它几乎相同。 – Hans

+0

@Hans:感谢您指出文章的MySQL版本。该文件说:'mysqldump以激活顺序转储触发器,以便在重新加载转储文件时,触发器以相同的激活顺序创建。 [5.5.4 mysqldump - 数据库备份程序](http://dev.mysql.com/doc/refman/5.7/en/mysqldump.html),这就是我无法确定问题出在哪里的原因。 – wchiquito

+0

是的,我看到了,但在我的输出中,每个触发器都包含完整的前/后语法,这意味着存在循环引用。它无法导入。我甚至使用'在一个交易'选项。 – Hans