当预定的事件发生时,事件触发器就会被触发。由于事件触发器设计的权限比较大,所以只有超级用户才能创建和修改触发器。

1. 事件触发器支持的事件分三类:ddl_command_startddl_command_end 和 sql_drop。

(1)ddl_command_start:在DDL开始前触发;

(2)ddl_command_end:在DDl结束后触发;

(3)sql_drop:删除一个数据库对象前被触发,其中删除的数据库对象详细信息,可以通过pg_event_trigger_dropped_objects()函数记录下来。

列名称列类型列描述
classidOid对象所在目录的Oid
objjdOid数据库对象的Oid
objsubidint32数据库对象的子对象 (如:列)
object_typetext数据库对象的类型
schema_nametext数据库对象的模式名
object_nametext数据库对象的名称
object_identifytext数据库对象的标识符

2. 各种DDL操作会触发的事件列表:

ALTER AGGREGATEXX-
ALTER COLLATIONXX-
ALTER CONVERSIONXX-
ALTER DOMAINXX-
ALTER EXTENSIONXX-
ALTER FOREIGN DATA WRAPPERXX-
ALTER FOREIGN TABLEXXX
ALTER FUNCTIONXX-
ALTER LANGUAGEXX-
ALTER OPERATORXX-
ALTER OPERATOR CLASSXX-
ALTER OPERATOR FAMILYXX-
ALTER SCHEMAXX-
ALTER SEQUENCEXX-
ALTER SERVERXX-
ALTER TABLEXXX
ALTER TEXT SEARCH CONFIGURATIONXX-
ALTER TEXT SEARCH DICTIONARYXX-
ALTER TEXT SEARCH PARSERXX-
ALTER TEXT SEARCH TEMPLATEXX-
ALTER TRIGGERXX-
ALTER TYPEXX-
ALTER USER MAPPINGXX-
ALTER VIEWXX-
CREATE AGGREGATEXX-
CREATE CASTXX-
CREATE COLLATIONXX-
CREATE CONVERSIONXX-
CREATE DOMAINXX-
CREATE EXTENSIONXX-
CREATE FOREIGN DATA WRAPPERXX-
CREATE FOREIGN TABLEXX-
CREATE FUNCTIONXX-
CREATE INDEXXX-
CREATE LANGUAGEXX-
CREATE OPERATORXX-
CREATE OPERATOR CLASSXX-
CREATE OPERATOR FAMILYXX-
CREATE RULEXX-
CREATE SCHEMAXX-
CREATE SEQUENCEXX-
CREATE SERVERXX-
CREATE TABLEXX-
CREATE TABLE ASXX-
CREATE TEXT SEARCH CONFIGURATIONXX-
CREATE TEXT SEARCH DICTIONARYXX-
CREATE TEXT SEARCH PARSERXX-
CREATE TEXT SEARCH TEMPLATEXX-
CREATE TRIGGERXX-
CREATE TYPEXX-
CREATE USER MAPPINGXX-
CREATE VIEWXX-
DROP AGGREGATEXXX
DROP CASTXXX
DROP COLLATIONXXX
DROP CONVERSIONXXX
DROP DOMAINXXX
DROP EXTENSIONXXX
DROP FOREIGN DATA WRAPPERXXX
DROP FOREIGN TABLEXXX
DROP FUNCTIONXXX
DROP INDEXXXX
DROP LANGUAGEXXX
DROP OPERATORXXX
DROP OPERATOR CLASSXXX
DROP OPERATOR FAMILYXXX
DROP OWNEDXXX
DROP RULEXXX
DROP SCHEMAXXX
DROP SEQUENCEXXX
DROP SERVERXXX
DROP TABLEXXX
DROP TEXT SEARCH CONFIGURATIONXXX
DROP TEXT SEARCH DICTIONARYXXX
DROP TEXT SEARCH PARSERXXX
DROP TEXT SEARCH TEMPLATEXXX
DROP TRIGGERXXX
DROP TYPEXXX
DROP USER MAPPINGXXX
DROP VIEWXXX
SELECT INTOXX-

3.  创建事件触发器的语法

CREATE EVENT TRIGGER name

ON EVENT

[ WHEN filter_variable IN ( filter_value [ , ... ]) [ AND ... ] ]

EXECUTE PROCEDURE function_name ()

4. 事件触发器示例

(1)禁止所有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();

--测试触发器
test=# drop table emp;
ERROR: command DROP TABLE is disabled
CONTEXT: PL/pgSQL function abort_any_command() line 3 at RAISE
test=# create table emp01 (x int);
ERROR: command CREATE TABLE is disabled
CONTEXT: PL/pgSQL function abort_any_command() line 3 at RAISE

test=# truncate table emp; --注意:truncate是在普通触发器中触发,在事件触发器中不会触发。
TRUNCATE TABLE --恢复DDL正常操作

test=# alter event trigger abort_ddl disable;
ALTER EVENT TRIGGER

(2)审计记录所有drop操作

--创建审计记录表
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_identify 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(); --测试触发器
test=# alter table emp drop column salary;
ALTER TABLE
test=#
test=# select ddl_tag,object_type,object_name,object_identity from log_drop_objects;
ddl_tag | object_type | object_name | object_identity
-------------+--------------+-------------+-------------------
ALTER TABLE | table column | | public.emp.salary
(1 row) test=#
test=# drop table emp;
DROP TABLE
test=#
test=# select ddl_tag,object_type,object_name,object_identity from log_drop_objects;
ddl_tag | object_type | object_name | object_identity
-------------+--------------+----------------------+-------------------------------
ALTER TABLE | table column | | public.emp.salary
DROP TABLE | table | emp | public.emp
DROP TABLE | type | emp | public.emp
DROP TABLE | type | _emp | public.emp[]
DROP TABLE | toast table | pg_toast_16461 | pg_toast.pg_toast_16461
DROP TABLE | index | pg_toast_16461_index | pg_toast.pg_toast_16461_index
DROP TABLE | type | pg_toast_16461 | pg_toast.pg_toast_16461
DROP TABLE | trigger | | emp_audit on public.emp
(8 rows)

5. 修改事件触发器

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

The End!

2017-08-20

05-21 10:59