当数据库中发生了与事件触发器绑定的特定系统事件时,该触发器会被自动触发执行。目前系统支持的核心事件包括:
login(用户登录连接)、
ddl_command_start(DDL 命令开始执行前)、
ddl_command_end(DDL 命令成功执行后)、
table_rewrite(数据表即将发生底层物理整表重写前)以及
sql_drop(任何数据库对象即将被删除前)。
当一个已完成身份认证的用户成功登录连接到数据库时触发。该事件触发器可用于会话审计日志记录、初始化用户专属的临时环境或校验登录时间窗口。请注意在编写 login 触发器时必须格外严谨:一旦该触发器函数内部发生未捕获的代码抛错崩溃,将导致任何用户都无法成功登录数据库!遇到此类紧急故障时,可以通过在连接串中设置 -c event_triggers=off 或重启单用户模式来紧急绕过并修复。
在任何 DDL 命令(如 CREATE、ALTER、DROP、GRANT、REVOKE 等)正式开始执行之前瞬间触发。常用于实施安全审计策略,在非法操作开始前主动抛出异常(RAISE EXCEPTION)予以阻断拦截。
在 DDL 命令顺利执行完成之后、事务提交之前触发。在该触发器函数内部,可以通过调用系统内置集合函数 pg_event_trigger_ddl_commands() 获取刚刚发生的 DDL 操作的完整对象清单(包含对象类型、模式名、对象标识等),极其适合构建自动化的企业级 Schema 变更审计日志库。
在执行任何对象的删除(DROP)操作时触发。在该函数内部通过调用 pg_event_trigger_dropped_objects(),能够完整遍历所有即将被销毁的对象元数据信息。
在数据表因执行特定 ALTER TABLE 操作而即将触发物理整表全页重写之前触发。在生产高可用环境中,整表物理重写会引发长时间的排他锁与巨额磁盘 I/O,利用该触发器可以在检测到危险重写时直接抛错拦截,防止业务高峰期发生意外锁表事故。
事件触发器(如同其他函数)无法在已异常中止的事务中执行。因此,若某条 DDL 命令执行失败报错,任何关联的 ddl_command_end 触发器均不会被执行。反之,若 ddl_command_start 触发器抛出错误,后续事件触发器不会被触发,且系统不会尝试执行该 DDL 命令本身。同样,若 ddl_command_end 触发器执行报错,该 DDL 语句产生的所有效果均会被自动回滚。
事件触发器通过 CREATE EVENT TRIGGER 命令创建。在创建事件触发器之前,必须先创建一个返回特殊类型 event_trigger 的函数。该函数无需(且严禁)返回值,该返回类型仅作为标识该函数将被作为事件触发器调用的信号。
若针对同一事件定义了多个事件触发器,它们将按触发器名称的字母表升序依次触发。
触发器定义中还可以声明 WHEN 条件,以便仅针对用户希望拦截的特定命令标签触发(如仅针对特定 DDL 操作进行访问权限校验拦截)。