如何阻止Hasura事件触发器生成新待处理事件及清理存量事件
解决方案与问题解答
一、更新表时避免触发Hasura事件触发器的正确方法
删除触发器再重建的方式不可行,因为Hasura重建触发器时会重新扫描表并生成新的待处理事件。最直接高效的方案是临时禁用触发器:
-- 禁用目标表上的指定事件触发器 ALTER TABLE your_target_table DISABLE TRIGGER your_trigger_name; -- 执行你的批量更新操作 UPDATE your_target_table SET ...; -- 更新完成后重新启用触发器 ALTER TABLE your_target_table ENABLE TRIGGER your_trigger_name;
这种方式不会生成任何冗余待处理事件,完全满足你的需求。
二、关于删除全部事件日志SQL的安全性
你提供的两条删除语句在确认待处理事件无业务价值的前提下是安全的,但需要注意以下几点:
- 执行前暂停Hasura事件处理器,避免删除过程中产生新事件或处理器正在处理事件导致冲突;
- 建议先备份系统表数据,防止误删需要回溯的信息:
-- 备份事件日志表 CREATE TABLE hdb_catalog.event_log_backup AS SELECT * FROM hdb_catalog.event_log; -- 备份事件调用日志表 CREATE TABLE hdb_catalog.event_invocation_logs_backup AS SELECT * FROM hdb_catalog.event_invocation_logs; - 直接删除会清除所有事件历史和待处理事件,执行后无法恢复(除非有备份)。
三、为什么之前的清理SQL只能删除数十条
Hasura对事件处理有锁机制,加上子查询效率限制,导致单条SQL只能处理少量数据。可以改用循环批量删除的方式清理指定触发器的待处理事件:
-- 循环批量删除,每次处理1000条,直到目标事件清理完毕 WHILE EXISTS ( SELECT 1 FROM hdb_catalog.event_log WHERE trigger_name = 'my_trigger_name' AND delivered = false AND created_at > now() - interval '2 days' ) LOOP DELETE FROM hdb_catalog.event_invocation_logs WHERE event_id IN ( SELECT id FROM hdb_catalog.event_log WHERE trigger_name = 'my_trigger_name' AND delivered = false AND created_at > now() - interval '2 days' LIMIT 1000 ); DELETE FROM hdb_catalog.event_log WHERE trigger_name = 'my_trigger_name' AND delivered = false AND created_at > now() - interval '2 days' LIMIT 1000; END LOOP;
内容的提问来源于stack exchange,提问作者Soham
相关产品推荐
相关产品推荐

