【问题标题】:Using triggers with different users (MySQL error 1449)对不同用户使用触发器(MySQL 错误 1449)
【发布时间】:2016-06-16 20:30:23
【问题描述】:

问题:如何从我的开发系统导出数据库内容(包括触发器)并将数据导入实时服务器,而不会在触发触发器时遇到错误 1449?

在最近的一个 php 项目中,我广泛使用了 mysql 触发器,但在将我的数据库从 dev 部署到 live 系统时遇到了问题。

例如我的触发器之一定义如下(使用mysqldump生成的输出)

DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER update_template BEFORE UPDATE ON template
FOR EACH ROW BEGIN
  SET new.mod_date := now();
END */;;
DELIMITER ;

该触发器是在我的开发系统上使用用户 root@localhost 定义的,该用户在上述语句中创建了 DEFINER=root@localhost 子句。

root@localhost 作为实时服务器上的用户不存在,这会在实时系统用户触发触发器(例如,通过使用 update templates set...)时导致以下错误

1449: 指定为定义者的用户('root'@'localhost') 不存在

目前我使用mysqldump --add-drop-table --user=root -p my_project > export.sql 用于导出,mysql -u devuser -p my_project < export.sql 用于导入数据。

导出/导入完美无缺。只有当我通过 sql 操作数据并涉及触发器时才会出现该错误。

编辑:

MySQL 版本是 5.5.47(live 和 dev)

【问题讨论】:

标签: mysql triggers mysqldump


【解决方案1】:

导出到export.sql 后,接下来需要通过 sed 使用正则表达式清理触发线,如下所示:

sed -i -- 's/^..!50003\sCREATE.....!50017\sDEFINER=.root...[^]*.....!50003\s\([^;]*\)/CREATE DEFINER=CURRENT_USER \1/g;s/^\s*\([^\*]*;\{0,1\}\)\s\{0,1\}\*\/;;$/\1;;/g' export.sql

这适用于 Linux,但如果您使用的是 Mac OS X,则内置的 sed 命令将不起作用。您需要先brew install gnu-sed,然后在上述命令中使用 gsed 而不是 sed

【讨论】:

    【解决方案2】:

    使用以下 sed 命令从转储文件中删除 DEFINER 部分,然后将其导入您的实时服务器。

    sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i dumpfile.sql
    

    默认情况下,触发器将由导入转储文件的用户创建。

    【讨论】:

      【解决方案3】:

      就我而言,导致问题的触发器没有BEGINEND 语句。所以我应用了相应的DROP TRIGGERCREATE TRIGGER,之后我再次进行了备份,后者恢复没有问题。即:

      DROP TRIGGER `incorrect_trg1`;
      DELIMITER ;;
      
      CREATE DEFINER = `root`@`localhost` TRIGGER `incorrect_trg1` BEFORE INSERT ON `table1` FOR EACH ROW 
      BEGIN
      SET NEW.col = DATE_FORMAT(NEW.col,'%Y%m');
      END;;
      
      DELIMITER ;
      

      【讨论】:

        猜你喜欢
        • 2012-04-27
        • 1970-01-01
        • 2019-06-19
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        • 2016-12-19
        • 1970-01-01
        相关资源
        最近更新 更多