2017-02-25 231 views

回答

4

Postgres 9.5有一個函數pg_event_trigger_ddl_commands()可以在事件觸發器中使用以獲取插入/更改對象的oid。

日誌表:

create table function_log (
    datetime timestamp, 
    schema_name text, 
    function_name text, 
    tag text, 
    function_body text); 

事件功能和觸發:

create or replace function public.on_function_event() 
    returns event_trigger 
    language plpgsql 
as $function$ 
begin 
    insert into function_log 
    select now(), nspname, proname, command_tag, prosrc 
    from pg_event_trigger_ddl_commands() e 
    join pg_proc p on p.oid = e.objid 
    join pg_namespace n on n.oid = pronamespace; 
end 
$function$; 

create event trigger on_function_event 
on ddl_command_end 
when tag in ('CREATE FUNCTION', 'ALTER FUNCTION') 
execute procedure on_function_event(); 

例子:

create or replace function test() 
returns int as $$ select 1; $$ language sql; 

create or replace function test() 
returns int as $$ select 2; $$ language sql; 

alter function test() immutable; 

select * 
from function_log; 

      datetime   | schema_name | function_name |  tag  | function_body 
----------------------------+-------------+---------------+-----------------+--------------- 
2017-02-26 13:05:15.353879 | public  | test   | CREATE FUNCTION | select 1; 
2017-02-26 13:05:15.353879 | public  | test   | CREATE FUNCTION | select 2; 
2017-02-26 13:05:15.353879 | public  | test   | ALTER FUNCTION | select 2; 
(3 rows) 

可以DROP FUNCTION命令標籤添加到扳機,然後使用功能pg_event_trigger_dropped_objects()以類似於pg_event_trigger_ddl_commands()的方式。

遺憾的是,在Postgres 9.4中沒有pg_event_trigger_ddl_commands()。您可以嘗試使用current_query()獲取插入/更改的對象,或在C中寫入觸發器函數。我認爲更簡單的方法是將Postgres升級到9.5+。

+0

感謝您的解決方案。你可以請建議,如果我可以在數據庫表中存儲日誌。 – Tajinder

+0

既然pg_dump不能保證像函數這樣的東西排序,那麼你認爲信噪比會是多少? –

+1

我的第一個回答是'pg_dump',可能太籠統了,所以我完全修改了答案。 – klin

1

的約束的幾個注意事項。

  1. 您不能在PostgreSQL的系統表上放置觸發器,因此在這方面無法創建審計跟蹤。
  2. 你可能需要使用一些外部的PostgreSQL的管理版本。所以我會推薦像sqitch這樣的東西。

pgdump的一個主要問題是事物的排序不能保證是唯一的,所以簡單的轉儲和版本會給你一個很糟糕的信噪比。

現在有一件事你可能做的是在ddl上使用event triggers來捕獲事件然後記錄和處理。這仍然需要您在設計方面付出很多努力,但完全有可能。如果您使用事件觸發器,請先在分級系統上進行徹底測試!

時候我已經需要做這樣的事情,我平時已經使用事件觸發器和系統表的副本,所以我更新從舊目錄表和日誌的變化,我會說。