當預定的事件發生時,事件觸發器就會被觸發。由於事件觸發器設計的權限比較大,所以只有超級用戶才能創建和修改觸發器。
1. 事件觸發器支持的事件分三類:ddl_command_start, ddl_command_end 和 sql_drop。
(1)ddl_command_start:在DDL開始前觸發;
(2)ddl_command_end:在DDl結束后觸發;
(3)sql_drop:刪除一個數據庫對象前被觸發,其中刪除的數據庫對象詳細信息,可以通過pg_event_trigger_dropped_objects()函數記錄下來。
列名稱 | 列類型 | 列描述 |
classid | Oid | 對象所在目錄的Oid |
objjd | Oid | 數據庫對象的Oid |
objsubid | int32 | 數據庫對象的子對象 (如:列) |
object_type | text | 數據庫對象的類型 |
schema_name | text | 數據庫對象的模式名 |
object_name | text | 數據庫對象的名稱 |
object_identify | text | 數據庫對象的標識符 |
2. 各種DDL操作會觸發的事件列表:
命令標記 | ddl_command_start | ddl_command_end | sql_drop |
---|---|---|---|
ALTER AGGREGATE | X | X | - |
ALTER COLLATION | X | X | - |
ALTER CONVERSION | X | X | - |
ALTER DOMAIN | 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 OPERATOR | X | X | - |
ALTER OPERATOR CLASS | X | X | - |
ALTER OPERATOR FAMILY | X | X | - |
ALTER SCHEMA | X | X | - |
ALTER SEQUENCE | X | X | - |
ALTER SERVER | X | X | - |
ALTER TABLE | 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 | - |
ALTER USER MAPPING | X | X | - |
ALTER VIEW | 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 OPERATOR | X | X | - |
CREATE OPERATOR CLASS | X | X | - |
CREATE OPERATOR FAMILY | X | X | - |
CREATE RULE | X | X | - |
CREATE SCHEMA | X | X | - |
CREATE SEQUENCE | X | X | - |
CREATE SERVER | 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 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 OPERATOR | X | X | X |
DROP OPERATOR CLASS | X | X | X |
DROP OPERATOR FAMILY | X | X | X |
DROP OWNED | X | X | X |
DROP RULE | X | X | X |
DROP SCHEMA | X | X | X |
DROP SEQUENCE | X | X | X |
DROP SERVER | 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 |
SELECT INTO | X | X | - |
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