Table based ddl (alter table) audit of Postgresql

If you want to record the user table modified and defined by DDL, set the default value, and so on, you can use event triggers to achieve this purpose.

Examples are as follows:

testdb=# create extension hstore;
testdb=# create or replace function ef_alter() returns event_trigger as $$
declare
rec hstore;
begin
select hstore(pg_stat_activity.*) into rec from pg_stat_activity where pid=pg_backend_pid();
insert into aud_alter (ctx) values (rec);
end;
$$ language plpgsql strict;
CREATE FUNCTION

testdb=# create event trigger e_alter on ddl_command_end when tag in ('ALTER TABLE') execute procedure ef_alter();
CREATE EVENT TRIGGER

testdb=# create table aud_alter(id serial primary key, crt_time timestamp default now(), ctx hstore);
CREATE TABLE

testdb=# create table test(id int);
CREATE TABLE

testdb=# alter table test alter column id type int8;
ALTER TABLE

testdb=# select * from aud_alter;
-[ RECORD 1 ]------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id       | 1
crt_time | 2018-05-03 13:44:12.309983
ctx      | "pid"=>"9408", "datid"=>"16384", "query"=>"alter table test alter column id type int8;", "state"=>"active", "datname"=>"testdb", "usename"=>"postgres", "waiting"=>"f", "usesysid"=>"10", "xact_start"=>"2018-05-03 13:44:12.309983+08", "backend_xid"=>"8367", "client_addr"=>NULL, "client_port"=>"-1", "query_start"=>"2018-05-03 13:44:12.309983+08", "backend_xmin"=>"8367", "state_change"=>"2018-05-03 13:44:12.309985+08", "backend_start"=>"2018-05-03 13:40:15.0561+08", "client_hostname"=>NULL, "application_name"=>"psql"

testdb=# select each(ctx) from aud_alter where id=1;
                         each                          
-------------------------------------------------------
 (pid,9408)
 (datid,16384)
 (query,"alter table test alter column id type int8;")
 (state,active)
 (datname,testdb)
 (usename,postgres)
 (waiting,f)
 (usesysid,10)
 (xact_start,"2018-05-03 13:44:12.309983+08")
 (backend_xid,8367)
 (client_addr,)
 (client_port,-1)
 (query_start,"2018-05-03 13:44:12.309983+08")
 (backend_xmin,8367)
 (state_change,"2018-05-03 13:44:12.309985+08")
 (backend_start,"2018-05-03 13:40:15.0561+08")
 (client_hostname,)
 (application_name,psql)
(18 rows)

query is then ALTER TABLE SQL

Other auxiliary information is the user's IP, PORT, user, linked database and so on.
If you only want to track the types of fields in the table before and after being modified, the more strict way is to take the modified fields and types out of parsetree.

by boluo

Keywords: SQL Database

Added by m4rw3r on Tue, 24 Mar 2020 17:11:38 +0200