我可以在 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 数据库中创建触发器吗?的主要内容,如果未能解决你的问题,请参考以下文章

RDS 触发器的 Lambda 函数访问导致连接丢失

我可以在 TRIGGER 中创建一个 MYSQL TRIGGER WITH 或条件吗

我可以从 Python 触发在 KV 文件中创建的屏幕吗?

我可以在 MS Access 2010 中创建存储过程吗?

RDS 服务触发 Lambda

如何定期运行在CDK中创建的Lambda?