我可以为您翻译:我能在RDS数据库中创建触发器吗?

57

我正在尝试在我的Amazon RDS数据库中的表上创建触发器,但似乎无法实现。

我尝试在我使用的mysql客户端(Navicat)上创建一个触发器,但出现了错误,提示我需要SUPER权限才能这样做。经过一些搜索,我发现您可以 SET GLOBAL log_bin_trust_function_creators = 1 来解决此问题。我按照以下说明尝试了这个方法:http://getasysadmin.com/2011/06/amazon-rds-super-privileges/ (然后为了保险起见重新启动了DB服务器),但没有成功。

我还尝试通过mysql命令行创建触发器并设置变量,以确保Navicat没有向我的SQL命令添加任何不必要的内容,但这也失败了。从搜索结果看,貌似没有办法为自己授予SUPER权限。

那么,在RDS中是否可能创建触发器呢?


在我看来,foxybagga的答案应该被接受,因为它比CLI变体更易于访问(Garvice不要介意)。 - Mr. Developerdude
7个回答

120

很简单!

打开RDS web控制台。

打开“参数组”选项卡。

创建一个新的参数组。 在对话框中,选择与您的MySQL数据库版本兼容的MySQL系列,给它一个名称并确认。

选择刚创建的参数组并发出“编辑参数”命令。

查找参数“log_bin_trust_function_creators”,并将其值设置为“1”。

保存更改。

打开“实例”选项卡。 展开您的MySQL实例并发出名为“修改”的“实例操作”。

选择刚创建的参数组并启用“立即应用”。

点击“继续”并确认更改。

再次打开“实例”选项卡。 展开您的MySQL实例并发出名为“修改”的“实例操作”。

别忘了:打开“实例”选项卡。 展开您的MySQL实例并发出名为“重启”的“实例操作”。

来源-http://techtavern.wordpress.com/2013/06/17/mysql-triggers-and-amazon-rds/


5
好的,谢谢!比命令行好多了,爽死了 :-) - JRun
3
这个很有效。如果你想从一个mysqldump文件中实现这个,还需要再进行一步。你需要删除DEFINER块才能创建触发器。这里有一篇关于如何做到这一点的好文章:http://www.percona.com/blog/2014/07/02/using-mysql-triggers-and-views-in-amazon-rds/ - vcardillo
1
这对我来说不起作用,你是否需要任何特殊的RDS“专用或非共享”之类的东西? - Miguel
3
重新启动!在我阅读的所有其他关于更新log_bin_trust_function_creators和修改实例的地方,没有人提到之后需要重新启动。回想起来有点显而易见,但这总是这样。感谢您结束了我的挣扎和自我怀疑 :) - Darragh Enright
1
直接来自 AWS - https://aws.amazon.com/premiumsupport/knowledge-center/rds-mysql-functions/ - JavaRocky
显示剩余4条评论

41

不,事实上并不是不可能,只是需要额外付出太多工作。

首先,似乎无法将超级权限应用于默认参数组。 因此,我不得不通过控制台或CLI创建一个新的DB参数组。

我发现关键在于默认区域不是我尝试使用的区域,因此我必须使用 --region 参数将其应用于正确区域中部署我的DB实例的组。

rds-create-db-parameter-group --db-parameter-group-name allow-triggers --description 'parameter group to allow triggers' --region your-region 

接下来我需要创建一个使用该参数组的DB实例。(同样可以通过控制台或CLI完成)

rds-create-db-instance

然后我不得不修改参数组,只能通过CLI实现log_bin_trust_function_creators

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

我现在没有测试的条件,但既然你被授予奖金,我认为这对某人有效。下次我一定会保存这个信息。谢谢! - tedders
那么你是如何解决这个问题的呢?我很好奇,因为这是我能够向RDS添加触发器的唯一方法。(而且花了我大约1.5天的时间从各种帮助线程中拼凑出碎片) - Garvice
1
我并不是想暗示我们已经解决了它,我们只是没有使用触发器。很好,你找到了这个问题,下次我会尝试一下。 - tedders
我该如何获取数据库实例ID?需要运行 rds-modify-db-instance --db-instance-identifier **your-db-instance-id** --db-parameter-group-name allow-triggers --apply-immediately 命令。 - GarouDan
5
通过RDS Web控制台,在参数部分将log_bin_trust_function_creators设置为1,我似乎已经成功使其运行。这也是@Garvice回答中的一个步骤,所以它不会有任何问题。 - Rupert Rawnsley
这是一个误导性的答案,实际上非常容易,在控制台上就可以完成。 - Nick

19
除了其他人已经提到的参数组修改之外,当使用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主用户名不同的“definer”条目。一种解决方法是将definer用户名替换为您的RDS主用户名。另一种解决方法是不使用mysqldump来创建数据库。
请参阅此博文获取更多信息:

http://www.percona.com/blog/2014/07/02/using-mysql-triggers-and-views-in-amazon-rds/


3
这正是我所面临的问题,谢谢你,威利! - Denys Kurochkin

8
编辑:原来MySQL的多AZ使用的是“物理复制”,而不是逻辑复制,因此这可能不正确。至少他们的文档是这样说的:https://aws.amazon.com/rds/details/multi-az/ - 我已经在他们的论坛上询问了这是什么意思,但没有得到回复。奇怪的是,我的RDS多AZ实例声称它是“复制设置中的主服务器”,尽管我没有读取副本。


既然问题已经解决,这只是一条评论而不是答案:

我很惊讶没有人考虑到默认情况下为什么不提供此功能。亚马逊不会禁用它只是为了让人们的生活更加困难。

在主/从复制中,使用存储过程和触发器修改数据(如执行查询而不是 SELECT)可能会很危险。

在禁用此限制之前,请先阅读以下内容,Amazon RDS在使用Multi-AZ时就是主/从设置(至少生产环境应该如此)。

http://dev.mysql.com/doc/refman/5.6/en/stored-programs-logging.html


问题可能直到很晚才变得明显(例如,在尝试进行时间点恢复时)! - Aaron Pollock

2
我按照上述方法操作但是没有成功。我花了将近一天的时间来找出原因,现在我知道了。我列出了我遵循的步骤以使其工作。
1. 使用AWS Web控制台创建MySQL参数组(确保它与默认参数组具有相同的系列)。早些时候,我创建了一个参数组,但它有不同的系列,所以它没有起作用。这是关键步骤。
2. 使用AWS Web控制台将“log_bin_trust_function_creators”的值更改为“1”。
3. 应用新的参数组。这是另一个关键步骤。
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/提供的详细信息。

1
对我来说,它按照@foxybagga的答案建议起作用,但我需要更新生成的SQL转储(来自mysqlworkbench),以将CURRENT_USER作为定义者。
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 */ ;

我希望这能帮助到遇到同样问题的人。


1

AWS介绍了如何在这篇文章中启用函数和触发器

  1. 为你的MySQL实例创建一个DB参数组: 登录AWS管理控制台并打开Amazon RDS 控制台。 在导航面板中,选择Parameter Groups。 选择Create Parameter Group。出现Create Parameter Group窗口。 对于Parameter Group Family,请选择参数组系列。 对于Group Name,请键入新的DB参数组名称。 对于Description,请输入新的DB参数组描述。 选择Create。 重要提示 创建DB参数组后,应该至少等待5分钟再创建使用该DB参数组的第一个DB实例。

有关创建DB参数组的更多信息,请参见Working with DB Parameter Groups - Creating a DB Parameter Group

  1. 修改新创建的参数组并设置以下参数: 在导航窗格中,选择“参数组”。可用的DB参数组以列表形式显示。 在列表中,选择要修改的参数组。 选择“编辑参数”并将以下参数设置为指定值: log_bin_trust_function_creators = 1 选择“保存更改”。 重要提示 修改DB参数组后,应等待至少5分钟再创建第一个使用该DB参数组的DB实例。

有关修改DB参数组的信息,请参阅“使用DB参数组 - 修改DB参数组中的参数”。

  1. 将RDS DB实例与新的或修改后的DB参数组相关联: 在导航窗格中,选择“实例”。 选择要与DB参数组相关联的DB实例。 在“实例操作”菜单上,选择“修改”。 在“修改DB实例”对话框中,在“数据库选项”下,选择要与DB实例相关联的参数组。更改此设置不会导致停机。参数组名称立即更改,但实际参数更改直到您在无故障情况下重新启动实例后才应用。 通过重新启动实例来应用更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接