暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Postgresql事件触发器

参考官网:

http://www.postgres.cn/docs/current/event-trigger-matrix.html

PostgreSQL从9.3版开始支持一种称为“Event Trigger”的触发器, 这种触发器主要用于弥补PostgreSQL以前版本不支持DDL触发器的不足。 目前, 事件触发器支持以下4种DDL事件。

  • ddl_command_start: DDL开始执行前被触发。
  • ddl_command_end: 一个DDL执行完成后被触发。
  • sql_drop: 删除数据库对象前被触发。
  • table_rewrite:在表被命令ALTER TABLE和 ALTER TYPE的某些动作重写之前发生。虽然其他控制语句(例如 CLUSTER和VACUUM)也可以用来重写表,但是它们不会触发table_rewrite事件。

未来的发行版 中可能会增加对更多事件的支持。

由于事件触发器涉及的权限较大, 比如能禁止DDL操作等, 所以只有超级用户才能创建和修改事件触发器。

下表为支持事件触发器的命令标签

命令标签 ddl_command_start ddl_command_end sql_drop table_rewrite 注释
ALTER AGGREGATE X X - -
ALTER COLLATION X X - -
ALTER CONVERSION X X - -
ALTER DOMAIN X X - -
ALTER DEFAULT PRIVILEGES X X - -
ALTER EXTENSION X X - -
ALTER FOREIGN DATA WRAPPER X X - -
ALTER FOREIGN TABLE X X X -
ALTER FUNCTION X X - -
ALTER LANGUAGE X X - -
ALTER LARGE OBJECT X X - -
ALTER MATERIALIZED VIEW X X - X
ALTER OPERATOR X X - -
ALTER OPERATOR CLASS X X - -
ALTER OPERATOR FAMILY X X - -
ALTER POLICY X X - -
ALTER PROCEDURE X X - -
ALTER PUBLICATION X X - -
ALTER ROUTINE X X - -
ALTER SCHEMA X X - -
ALTER SEQUENCE X X - -
ALTER SERVER X X - -
ALTER STATISTICS X X - -
ALTER SUBSCRIPTION X X - -
ALTER TABLE X X X X
ALTER TEXT SEARCH CONFIGURATION X X - -
ALTER TEXT SEARCH DICTIONARY X X - -
ALTER TEXT SEARCH PARSER X X - -
ALTER TEXT SEARCH TEMPLATE X X - -
ALTER TRIGGER X X - -
ALTER TYPE X X - X
ALTER USER MAPPING X X - -
ALTER VIEW X X - -
COMMENT X X - - 仅对本地对象
CREATE ACCESS METHOD X X - -
CREATE AGGREGATE X X - -
CREATE CAST X X - -
CREATE COLLATION X X - -
CREATE CONVERSION X X - -
CREATE DOMAIN X X - -
CREATE EXTENSION X X - -
CREATE FOREIGN DATA WRAPPER X X - -
CREATE FOREIGN TABLE X X - -
CREATE FUNCTION X X - -
CREATE INDEX X X - -
CREATE LANGUAGE X X - -
CREATE MATERIALIZED VIEW X X - -
CREATE OPERATOR X X - -
CREATE OPERATOR CLASS X X - -
CREATE OPERATOR FAMILY X X - -
CREATE POLICY X X - -
CREATE PROCEDURE X X - -
CREATE PUBLICATION X X - -
CREATE RULE X X - -
CREATE SCHEMA X X - -
CREATE SEQUENCE X X - -
CREATE SERVER X X - -
CREATE STATISTICS X X - -
CREATE SUBSCRIPTION X X - -
CREATE TABLE X X - -
CREATE TABLE AS X X - -
CREATE TEXT SEARCH CONFIGURATION X X - -
CREATE TEXT SEARCH DICTIONARY X X - -
CREATE TEXT SEARCH PARSER X X - -
CREATE TEXT SEARCH TEMPLATE X X - -
CREATE TRIGGER X X - -
CREATE TYPE X X - -
CREATE USER MAPPING X X - -
CREATE VIEW X X - -
DROP ACCESS METHOD X X X -
DROP AGGREGATE X X X -
DROP CAST X X X -
DROP COLLATION X X X -
DROP CONVERSION X X X -
DROP DOMAIN X X X -
DROP EXTENSION X X X -
DROP FOREIGN DATA WRAPPER X X X -
DROP FOREIGN TABLE X X X -
DROP FUNCTION X X X -
DROP INDEX X X X -
DROP LANGUAGE X X X -
DROP MATERIALIZED VIEW X X X -
DROP OPERATOR X X X -
DROP OPERATOR CLASS X X X -
DROP OPERATOR FAMILY X X X -
DROP OWNED X X X -
DROP POLICY X X X -
DROP PROCEDURE X X X -
DROP PUBLICATION X X X -
DROP ROUTINE X X X -
DROP RULE X X X -
DROP SCHEMA X X X -
DROP SEQUENCE X X X -
DROP SERVER X X X -
DROP STATISTICS X X X -
DROP SUBSCRIPTION X X X -
DROP TABLE X X X -
DROP TEXT SEARCH CONFIGURATION X X X -
DROP TEXT SEARCH DICTIONARY X X X -
DROP TEXT SEARCH PARSER X X X -
DROP TEXT SEARCH TEMPLATE X X X -
DROP TRIGGER X X X -
DROP TYPE X X X -
DROP USER MAPPING X X X -
DROP VIEW X X X -
GRANT X X - - 只对本地对象
IMPORT FOREIGN SCHEMA X X - -
REFRESH MATERIALIZED VIEW X X - -
REVOKE X X - - 只对本地对象
SECURITY LABEL X X - - 只对本地对象
SELECT INTO X X - -

创建事件触发器的语法:

CREATE EVENT TRIGGER name
ON event
[ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ]
EXECUTE PROCEDURE function_name()

在创建事件触发器之前, 必须先创建触发器函数, 事件触发器函数的返回类型为event_trigger, 注意, 其与普通触发器函数的返回类型(trigger) 是不一样的。

官方手册中讲解了一个禁止所有DDL语句的示例, 命令如下:

CREATE OR REPLACE FUNCTION abort_any_command()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$
BEGIN
RAISE EXCEPTION 'command % is disabled', tg_tag;
END;
$$;
CREATE EVENT TRIGGER abort_DDL ON DDL_command_start
EXECUTE PROCEDURE abort_any_command();

按该示例创建事件触发器, 然后现在执行DDL语句将会报错(truncate table语句除外,因为在PostgreSQL中truncate事件是使用普通触发器触发的, 事件触发器是不会触发truncate table的)。

另外, 事件触发器本身的操作是不会再触发事件触发器的, 否则禁止DDL语句后,数据库就无法再执行DDL操作了, 这显然是不行的。
对于上面的例子, 如果想再次允许DDL操作, 可以禁止事件触发器, 语句如下:

ALTER EVENT TRIGGER abort_ddl DISABLE;

只在一个事务期间禁用该触发器会比较方便。

查询系统视图“pg_event_trigger”可以看到已有的事件触发器:

select * from pg_event_trigger ;

创建一个事件触发器, 用于记录表、 索引、 视图等所有数据库对象删除操作的审
计日志:

CREATE TABLE log_drop_objects(
op_time timestamp, --实际执行的时间
ddl_tag text, --记录实际的DDL类型
classid Oid,
objid Oid,
objsubid OID,
object_type text,
schema_name text,
object_name text,
object_identity text
);

CREATE FUNCTION event_trigger_log_drops()
RETURNS event_trigger LANGUAGE plpgsql AS $$
DECLARE
obj record;
BEGIN
INSERT INTO log_drop_objects SELECT now(), tg_tag, classid,objid,objsubid,object_type,schema_name,object_name, object_identity FROM pg_event_trigger_dropped_objects();
END
$$;

CREATE EVENT TRIGGER event_trigger_log_drops
ON sql_drop
EXECUTE PROCEDURE event_trigger_log_drops();

修改事件触发器的语法如下:

ALTER EVENT TRIGGER name DISABLE
ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
ALTER EVENT TRIGGER name OWNER TO new_owner
ALTER EVENT TRIGGER name RENAME TO new_name
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论