参考官网:
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




