在大型更新时从 mysql 触发器向 gearman 发送作业

Posted

技术标签:

【中文标题】在大型更新时从 mysql 触发器向 gearman 发送作业【英文标题】:Sending a job to gearman from a mysql trigger on large updates 【发布时间】:2019-10-26 14:15:30 【问题描述】:

我正在使用 gearman 的 udf 从更新后触发器向 gearman 发送后台作业。

文档说明如下:

gman_do* 函数采用可选的第三个参数,即 唯一的作业 ID。这允许您在同一个下提交多个作业 唯一 ID,它们将在队列中“合并”,仅运行一次。 请注意,gearmand 只会合并队列中或正在运行的作业, 作业完成后,它不会跟踪唯一 ID。例如, 以下确保您只为每个主机运行一次作业:

SELECT gman_do_background("reverse", Host, Host) AS test FROM mysql.user;

这使它看起来已经准备好处理大量行更新而不会淹没我的齿轮人的队列。

但是当我一次更新 30k 行时,我的 gearman 守护程序会在一段时间内无法访问,并且“netstat”在 4730 端口上显示了大约 30k 连接,我想这可以解释原因。

知道如何在不减慢更新速度的情况下防止冻结发生吗?我只需要在整个更新查询后触发一次 gearman 作业,但据我所知,mysql/mariadb 不处理语句后触发器。

【问题讨论】:

【参考方案1】:

MySQL/MariaDB 仅支持执行 FOR EACH ROW 的触发器(您可能已经注意到触发器语法中的这一强制性部分)。

无论如何,我绝不建议在触发器中调用 Gearman UDF。您无法在触发器中知道生成触发器的更新是否将被提交(或何时将被提交)。 gearman 服务可能会收到有关它无法查看的更新的通知,因为它尚未提交。

相反,忘记触发器。在您的应用程序中编写代码以进行更新,然后确认它成功并且事务已提交。然后才通知 gearman — 通过从您的应用调用 gearman API,而不是使用 MySQL UDF。

然后您可以灵活地为一批更新的行发出一个通知。

几乎没有什么好的方法可以在 MySQL 中使用任何会导致事务范围之外的副作用的 UDF,而且无论如何也没有必要这样做。

【讨论】:

将要求我删除数据库中的每个触发器,因为我试图响应的是其他一些触发器所做的更新。在这一点上,重写整个 10 年应用程序/数据库不是一种选择。我也不介意齿轮工工作部分可能出现的故障;那里没有做任何重要的事情。

以上是关于在大型更新时从 mysql 触发器向 gearman 发送作业的主要内容,如果未能解决你的问题,请参考以下文章

在当前快速打开菜单时从 NSTimer 动态更新 NSMenuItem?

创建一个名为stu_insert的触发器,当向学生表student中插入记录时,自动更新班级表class中的学生人数numbe

SQL TRIGGER 更新时从一张表到另一张表

更新触发器以将两个不同表中的数据添加到审计表中

MySQL中表的复制以及大型数据表的备份教程

如果在 ios 中收到通知时从后台删除应用程序,didReceiveLocalNotification 不会触发