我可以在 rds 数据库中创建触发器吗?
Posted
技术标签:
【中文标题】我可以在 rds 数据库中创建触发器吗?【英文标题】:Can I CREATE TRIGGER in an rds DB? 【发布时间】:2012-02-13 17:58:54 【问题描述】:我正在尝试在我的 Amazon RDS 数据库中的表上创建触发器,但我似乎无法实现。
我试图在我使用的 mysql 客户端 (Navicat) 中的表上创建一个触发器,并得到了我需要 SUPER 权限才能执行此操作的错误。经过一番搜索,我发现你可以SET GLOBAL log_bin_trust_function_creators = 1
来解决这个问题。我尝试使用以下说明:http://getasysadmin.com/2011/06/amazon-rds-super-privileges/(然后重新启动数据库服务器以获得良好的效果),但没有运气。
我还尝试通过 mysql 命令行创建触发器并设置变量,以确保 Navicat 没有向我的 sql 命令添加任何不需要的内容,但这也失败了。通过搜索似乎也没有办法授予自己 SUPER 特权。
那么...是否可以在 RDS 中创建触发器?
【问题讨论】:
foxybagga 的答案应该是公认的 imo,因为它比 CLI 变体更易于访问(没有冒犯 Garvice)。 【参考方案1】:不,实际上并非不可能,只是需要太多额外的工作。
首先,将超级权限应用于默认参数组似乎是不可能的。 所以我必须做的是通过控制台或 CLI 创建一个新的数据库参数组。
我发现,关键是默认区域不是我尝试使用的区域,因此我必须使用 --region 参数将其应用于我所在的正确区域中的组部署我的数据库实例
rds-create-db-parameter-group --db-parameter-group-name allow-triggers --description 'parameter group to allow triggers' --region your-region
接下来我必须创建一个使用该参数组的数据库实例。 (再次通过控制台或 CLI)
rds-create-db-instance
然后我不得不修改参数组以允许 log_bin_trust_function_creators 只能通过 CLI 完成
rds-modify-db-parameter-group --db-parameter-group-name yourgroupname --region yourRegion --parameters 'name=log_bin_trust_function_creators,value=true,method=immediate'
最后我必须修改创建的数据库实例以允许触发器,也仅限 CLI。
rds-modify-db-instance --db-instance-identifier your-db-instance-id --db-parameter-group-name allow-triggers --apply-immediately
【讨论】:
我现在无法对此进行测试,但我认为这对某人有用,因为您获得了赏金。下次我一定会把它归档。谢谢! 那么您是如何解决这个问题的呢?我很好奇,因为这是我能够向 RDS 添加触发器的唯一方法。 (我花了大约 1.5 天的时间拼凑来自各种帮助线程的点点滴滴) 我并不是要暗示我们解决了它,我们只是没有触发器。很高兴发现这一点,下次我会试一试。 如何获取数据库实例ID?需要运行rds-modify-db-instance --db-instance-identifier **your-db-instance-id** --db-parameter-group-name allow-triggers --apply-immediately
?
我似乎已经能够通过 RDS Web 控制台通过简单地将参数部分中的 log_bin_trust_function_creators 设置为 1 来完成这项工作。无论如何,这是@Garvic 答案中的步骤之一,所以不会有任何伤害。【参考方案2】:
对我来说,它就像 @foxybagga 的 answer 建议的那样工作,但我需要更新生成的 sql 转储(来自 mysqlworkbench)以将 CURRENT_USER 作为 DEFINER
即:
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=CURRENT_USER*/ /*!50003 TRIGGER `sod_db`.`date`
BEFORE INSERT ON `sod_db`.`CashOut`
FOR EACH ROW
BEGIN
SET NEW.created = NOW();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
我希望这可以帮助遇到同样问题的人。
【讨论】:
【参考方案3】:编辑:事实证明 MySQL 的多可用区使用“物理复制”而不是逻辑复制,因此这可能不正确。至少他们的文档是这么说的:https://aws.amazon.com/rds/details/multi-az/ - 我在他们的论坛上问过这意味着什么,但没有得到答复。奇怪的是,我的 RDS 多可用区实例声称它是“复制设置中的主实例”,即使我没有只读副本。
由于问题已经得到解决,这是一个评论而不是一个答案:
我很惊讶没有人考虑为什么此功能默认不可用。亚马逊不会为了让人们的生活更艰难而禁用它。
在主/从复制中,使用存储过程和修改数据的触发器可能很危险(例如在执行 SELECT 以外的查询时)。
在主/从设置中禁用此限制之前,请阅读以下内容,当您使用多可用区时,Amazon RDS 就是这样(至少在生产环境中您应该这样做)。
http://dev.mysql.com/doc/refman/5.6/en/stored-programs-logging.html
【讨论】:
而且问题可能要到很久以后才会显现出来(例如,在尝试进行时间点恢复时)!【参考方案4】:AWS 在this post 中列出了如何启用函数和triggers
-
为您的 MySQL 实例创建一个数据库参数组:
登录 AWS 管理控制台并打开 Amazon RDS console。
在导航窗格中,选择参数组。
选择创建参数组。出现创建参数组窗口。
对于参数组系列,选择参数组系列。
对于 Group Name,键入新数据库参数组的名称。
对于描述,键入新数据库参数组的描述。
选择创建。
重要的
创建数据库参数组后,您应该等待至少 5 分钟,然后再创建使用该数据库参数组的第一个数据库实例。
有关创建数据库参数组的更多信息,请参阅使用数据库参数组 - Creating a DB Parameter Group.
-
修改新建的参数组,设置如下参数:
在导航窗格中,选择参数组。可用的数据库参数组显示在列表中。
在列表中,选择要修改的参数组。
选择编辑参数并将以下参数设置为指定值:
log_bin_trust_function_creators = 1
选择保存更改。
重要的
修改数据库参数组后,您应该等待至少 5 分钟,然后再创建使用该数据库参数组的第一个数据库实例。
有关修改数据库参数组的信息,请参阅使用数据库参数组 - 修改数据库参数组中的参数。
-
将您的 RDS 数据库实例与新的或修改的数据库参数组相关联:
在导航窗格中,选择实例。
选择要与数据库参数组关联的数据库实例。
在实例操作菜单上,选择修改。
在 Modify DB Instance 对话框中的 Database Options 下,选择要与数据库实例关联的参数组。更改此设置不会导致中断。参数组名称会立即更改,但在您重新启动实例而不进行故障转移之前,不会应用实际的参数更改。
通过重启实例应用更改。
【讨论】:
【参考方案5】:除了其他人已经提到的参数组修改之外,在使用 MySQL 数据库转储(通过 mysqldump)在 AWS RDS 实例中创建触发器时还会出现进一步的挑战。您可能会收到这样的消息:
ERROR 1227 (42000) at line 875: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
发生这种情况是因为转储中包含用户名与您的 RDS 主用户名不同的“定义器”条目。一种解决方案是将定义者用户名替换为您的 RDS 主用户名。另一种解决方案是不使用 mysqldump 创建数据库。
查看这篇博文了解更多信息:
http://www.percona.com/blog/2014/07/02/using-mysql-triggers-and-views-in-amazon-rds/
【讨论】:
这正是我所面临的,谢谢,威利!【参考方案6】:很简单!
打开 RDS Web 控制台。
打开“参数组”选项卡。
创建一个新的参数组。在对话框中,选择与您的 MySQL 数据库版本兼容的 MySQL 系列,为其命名并确认。
选择刚刚创建的参数组并发出“编辑参数”。
查找参数“log_bin_trust_function_creators”并将其值设置为“1”。
保存更改。
打开“实例”选项卡。展开您的 MySQL 实例并发出名为“Modify”的“Instance Action”。
选择刚刚创建的参数组并启用“立即应用”。
点击“继续”并确认更改。
再次打开“实例”选项卡。展开您的 MySQL 实例并发出名为“Modify”的“Instance Action”。
不要忘记:打开“实例”选项卡。展开您的 MySQL 实例并发出名为“Reboot”的“Instance Action”。
通过 - http://techtavern.wordpress.com/2013/06/17/mysql-triggers-and-amazon-rds/
【讨论】:
酷。谢谢!击败 CLI :-) 很高兴看到亚马逊终于在 RDS Web 控制台中实现了这一点!在 CLI 中做这件事太痛苦了 这很好用。如果您尝试从 mysqldump 文件执行此操作,还有一步。您需要删除 DEFINER 块才能创建触发器。这是一篇关于这样做的好文章:percona.com/blog/2014/07/02/… 不知何故这对我不起作用..您是否必须有任何特殊的 RDS“专用或非共享”或类似的东西? REBOOT! 在所有其他地方,我读到了有关更新log_bin_trust_function_creators
和修改实例的信息,没有其他人提到之后重新启动。回想起来有点明显,但总是这样。谢谢你结束了我的挫败感和自我怀疑:)【参考方案7】:
我遵循了上述方法,但它对我不起作用。我花了将近一天的时间来弄清楚为什么它不起作用,现在我知道为什么了。我列出了我为使其工作而遵循的步骤。
使用 aws web 控制台创建 mysql 参数组(确保它应该与默认参数组具有相同的系列。之前,我创建了一个参数组,但它有不同的系列,所以它不起作用。这是关键步骤.
使用 aws Web 控制台将 log_bin_trust_function_creators
的值更改为 1
应用新的参数组。这是另一个关键步骤
rds-modify-db-instance –I $AWS_ACCESS_KEY –S $AWS_SECRET_KEY –region $EC2_REGION \ –db-instance-identifier $DB_INSTANCE \
–db-parameter-group-name $DB_GROUPNAME \
–apply-immediately
您需要来自 - http://s3.amazonaws.com/rds-downloads/RDSCli.zip 的 RDSCli
然后验证参数组是否与您的数据库实例相关联
rds-describe-db-instances \
–I $AWS_ACCESS_KEY \
–S $AWS_SECRET_KEY \
–region $EC2_REGION
然后在尝试创建触发器之前重新启动
rds-reboot-db-instance \
–I $AWS_ACCESS_KEY \
–S $AWS_SECRET_KEY \
–region $EC2_REGION \
–db-instance-identifier $DB_INSTANCE
请记住在尝试上述命令之前设置以下环境变量。
export AWS_ACCESS_KEY=’*****’
export AWS_SECRET_KEY=’*****’
export EC2_REGION=’region’
export AWS_RDS_BIN=”$AWS_RDS_HOME/bin”
export PATH=$PATH:$AWS_RDS_BIN
export JAVA_HOME=c:/jdk1.6_25 (in most cases this is already set)
感谢http://blog.iprofs.nl/2013/03/20/rds-database-triggers-for-mysql/ 提供详细信息。
【讨论】:
以上是关于我可以在 rds 数据库中创建触发器吗?的主要内容,如果未能解决你的问题,请参考以下文章