Inhaltsverzeichnis
PostgreSQL DDL Audit Logging
Diese Dokumentation beschreibt die Einrichtung eines einfachen DDL-Audit-Loggings in PostgreSQL. Ziel ist es, alle relevanten DDL-Kommandos wie CREATE, ALTER, DROP usw. nachvollziehbar zu protokollieren. Dazu werden Event Trigger und benutzerdefinierte Funktionen verwendet, die Informationen über ausgeführte Kommandos in einer zentralen Tabelle speichern.
Audit-Tabelle
Zunächst wird die Tabelle `ddl_audit_log` erstellt, die alle relevanten Informationen wie Befehlstyp, Objektname, Benutzer und Zeitstempel enthält:
CREATE TABLE IF NOT EXISTS public.ddl_audit_log ( id serial NOT NULL, command_tag text, object_type text, schema_name text, object_name text, executed_by text DEFAULT CURRENT_USER, executed_at TIMESTAMP WITH TIME zone DEFAULT CURRENT_TIMESTAMP, strg text, CONSTRAINT ddl_audit_log_pkey PRIMARY KEY (id) );
Die Spalte `executed_at` verwendet `CURRENT_TIMESTAMP`, um den Zeitpunkt der Einfügung zu erfassen. Optional kann dieser Wert auch explizit in den Triggerfunktionen gesetzt werden, falls Inserts verzögert oder asynchron erfolgen.
Event Trigger
Um DDL-Kommandos zu erfassen, werden zwei Event Trigger definiert. Der erste reagiert auf das Ende eines DDL-Kommandos, der zweite auf DROP-Operationen:
CREATE EVENT TRIGGER ddl_audit_trigger ON DDL_COMMAND_END EXECUTE PROCEDURE public.log_ddl_command(); CREATE EVENT TRIGGER ddl_drop_audit_trigger ON SQL_DROP EXECUTE PROCEDURE public.log_ddl_drop();
Funktion: log_ddl_command()
Diese Funktion verarbeitet alle DDL-Kommandos außer DROP. Sie nutzt `pg_event_trigger_ddl_commands()` und extrahiert relevante Informationen aus dem DDL-Kontext:
CREATE OR REPLACE FUNCTION public.log_ddl_command() RETURNS event_trigger LANGUAGE plpgsql AS $$ DECLARE ddl_record RECORD; BEGIN FOR ddl_record IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP INSERT INTO public.ddl_audit_log ( command_tag, object_type, schema_name, object_name, executed_by, strg ) VALUES ( ddl_record.command_tag, ddl_record.object_type, split_part(ddl_record.object_identity, '.', 1), split_part(ddl_record.object_identity, '.', 2), CURRENT_USER, current_query() ); END LOOP; END; $$;
Funktion: log_ddl_drop()
DROP-Kommandos werden separat behandelt, da sie über `pg_event_trigger_dropped_objects()` erfasst werden. Der Befehlstyp wird manuell auf `'DROP'` gesetzt:
CREATE OR REPLACE FUNCTION public.log_ddl_drop() RETURNS event_trigger LANGUAGE plpgsql AS $$ DECLARE obj RECORD; BEGIN FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() LOOP INSERT INTO public.ddl_audit_log ( command_tag, object_type, schema_name, object_name, executed_by ) VALUES ( 'DROP', obj.object_type, split_part(obj.object_identity, '.', 1), split_part(obj.object_identity, '.', 2), CURRENT_USER ); END LOOP; END; $$;
Weitere Triggerpunkte
PostgreSQL bietet mehrere eingebaute Event-Zeitpunkte, die für erweitertes Logging genutzt werden können:
| Event-Zeitpunkt | Beschreibung |
|---|---|
| `ddl_command_start` | Wird ausgelöst zu Beginn eines DDL-Kommandos. |
| `ddl_command_end` | Wird ausgelöst nach erfolgreichem Abschluss eines DDL-Kommandos. |
| `sql_drop` | Wird ausgelöst bei DROP-Operationen. |
| `table_rewrite` | Wird ausgelöst, wenn eine Tabelle intern neu geschrieben wird. |
