<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="http://wiki.redatek.de/lib/exe/css.php?s=feed" type="text/css"?>
<rdf:RDF
    xmlns="http://purl.org/rss/1.0/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel rdf:about="http://wiki.redatek.de/feed.php">
        <title>dynaDAT | UNIXoni | REDATEK | ITVeteran  - postgres</title>
        <description></description>
        <link>http://wiki.redatek.de/</link>
        <image rdf:resource="http://wiki.redatek.de/_media/logo.png" />
       <dc:date>2026-07-29T11:23:11+00:00</dc:date>
        <items>
            <rdf:Seq>
                <rdf:li rdf:resource="http://wiki.redatek.de/postgres:daemon_listener?rev=1777791716&amp;do=diff"/>
                <rdf:li rdf:resource="http://wiki.redatek.de/postgres:ddl_logging?rev=1777794338&amp;do=diff"/>
                <rdf:li rdf:resource="http://wiki.redatek.de/postgres:statistik_und_audit?rev=1777794334&amp;do=diff"/>
            </rdf:Seq>
        </items>
    </channel>
    <image rdf:about="http://wiki.redatek.de/_media/logo.png">
        <title>dynaDAT | UNIXoni | REDATEK | ITVeteran </title>
        <link>http://wiki.redatek.de/</link>
        <url>http://wiki.redatek.de/_media/logo.png</url>
    </image>
    <item rdf:about="http://wiki.redatek.de/postgres:daemon_listener?rev=1777791716&amp;do=diff">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-03T07:01:56+00:00</dc:date>
        <dc:creator>Anonymous (anonymous@undisclosed.example.com)</dc:creator>
        <title>daemon_listener</title>
        <link>http://wiki.redatek.de/postgres:daemon_listener?rev=1777791716&amp;do=diff</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;postgresqllisten_notify-daemon_fuer_automatische_datenbank-erstellung&quot;&gt;PostgreSQL: Listen/Notify-Daemon für automatische Datenbank-Erstellung&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Kurznotiz zum Projekt &lt;strong&gt;db_listener&lt;/strong&gt; im Repo &lt;a href=&quot;https://github.com/schillingbtk/postgresql_snippets/tree/main/daemon_listener&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/schillingbtk/postgresql_snippets/tree/main/daemon_listener&quot; rel=&quot;ugc nofollow&quot;&gt;postgresql_snippets / daemon_listener&lt;/a&gt;: Ein dauerhaft laufender Python-Dienst lauscht per &lt;strong&gt;LISTEN&lt;/strong&gt; auf dem Kanal `create_database`. Nach einem &lt;strong&gt;`NOTIFY create_database, &amp;#039;&amp;lt;dbname&amp;gt;&amp;#039;`&lt;/strong&gt; wird die genannte Datenbank angelegt und per SQL-Skripte mit Schema, Rollen und Rechten initialisiert.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;PostgreSQL: Listen\/Notify-Daemon f\u00fcr automatische Datenbank-Erstellung&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;postgresqllisten_notify-daemon_fuer_automatische_datenbank-erstellung&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-504&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;einordnung&quot;&gt;Einordnung&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Das gehört thematisch zu &lt;strong&gt;PostgreSQL-Betrieb und Automatisierung&lt;/strong&gt; (neben den übrigen Notizen unter &lt;code&gt;postgres:&lt;/code&gt; zu DDL-Audit und Statistik). Es ist &lt;strong&gt;kein&lt;/strong&gt; Replikations- oder Low-Level-Protokoll-Listener, sondern ein &lt;strong&gt;Anwendungs-Daemon&lt;/strong&gt;, der &lt;strong&gt;Benachrichtigungen&lt;/strong&gt; nutzt, um &lt;strong&gt;Provisionierung&lt;/strong&gt; asynchron auszulösen.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Einordnung&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;einordnung&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;505-855&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;technik_ueberblick&quot;&gt;Technik (Überblick)&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Laufzeit: Python 3 mit &lt;strong&gt;psycopg2&lt;/strong&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Steuerverbindung typischerweise zur Datenbank &lt;code&gt;postgres&lt;/code&gt; (im Originalbeispiel Port 6432 — oft PgBouncer; Rolle &lt;strong&gt;creator&lt;/strong&gt;)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Schleife: &lt;strong&gt;LISTEN create_database&lt;/strong&gt;, Warten, Payload = Datenbankname, danach &lt;code&gt;CREATE DATABASE&lt;/code&gt; und Abarbeiten der mitgelieferten SQL-Dateien (u. a. &lt;code&gt;init_managed_database.sql&lt;/code&gt;, &lt;code&gt;create_managed_schema.sql&lt;/code&gt;)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Bereitstellung über &lt;strong&gt;systemd&lt;/strong&gt; (&lt;code&gt;db_listener.service&lt;/code&gt;, Benutzer z. B. &lt;code&gt;sqladmin&lt;/code&gt;)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Technik (\u00dcberblick)&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;technik_ueberblick&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;856-1371&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;stichworte&quot;&gt;Stichworte&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;em&gt;PostgreSQL, LISTEN, NOTIFY, Provisionierung, Python, systemd, db_listener, psycopg2&lt;/em&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Stichworte&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;stichworte&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1372-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.redatek.de/postgres:ddl_logging?rev=1777794338&amp;do=diff">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-03T07:45:38+00:00</dc:date>
        <dc:creator>Anonymous (anonymous@undisclosed.example.com)</dc:creator>
        <title>ddl_logging</title>
        <link>http://wiki.redatek.de/postgres:ddl_logging?rev=1777794338&amp;do=diff</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;postgresql_ddl_audit_logging&quot;&gt;PostgreSQL DDL Audit Logging&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;http://wiki.redatek.de/lib/images/smileys/exclaim.svg&quot; class=&quot;icon smiley&quot; alt=&quot;:!:&quot; /&gt; &lt;strong&gt;Verwandter Artikel:&lt;/strong&gt; Auswertung, &lt;code&gt;pg_stat_statements&lt;/code&gt; und Betriebshinweise: &lt;a href=&quot;http://wiki.redatek.de/postgres:statistik_und_audit&quot; class=&quot;wikilink1&quot; title=&quot;postgres:statistik_und_audit&quot; data-wiki-id=&quot;postgres:statistik_und_audit&quot;&gt;PostgreSQL DDL-Audit Setup&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;PostgreSQL DDL Audit Logging&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;postgresql_ddl_audit_logging&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-552&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;audit-tabelle&quot;&gt;Audit-Tabelle&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Zunächst wird die Tabelle `ddl_audit_log` erstellt, die alle relevanten Informationen wie Befehlstyp, Objektname, Benutzer und Zeitstempel enthält:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;EXISTS&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
  id serial &lt;span class=&quot;kw1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  command_tag text&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  object_type text&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  schema_name text&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  object_name text&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  executed_by text &lt;span class=&quot;kw1&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  executed_at &lt;span class=&quot;kw1&quot;&gt;TIMESTAMP&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;WITH&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;TIME&lt;/span&gt; zone &lt;span class=&quot;kw1&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  strg text&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;CONSTRAINT&lt;/span&gt; ddl_audit_log_pkey &lt;span class=&quot;kw1&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Audit-Tabelle&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;audit-tabelle&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;553-1307&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;event_trigger&quot;&gt;Event Trigger&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Um DDL-Kommandos zu erfassen, werden zwei Event Trigger definiert.  
Der erste reagiert auf das Ende eines DDL-Kommandos, der zweite auf DROP-Operationen:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_audit_trigger &lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; DDL_COMMAND_END
  &lt;span class=&quot;kw1&quot;&gt;EXECUTE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;PROCEDURE&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_command&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_drop_audit_trigger &lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; SQL_DROP
  &lt;span class=&quot;kw1&quot;&gt;EXECUTE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;PROCEDURE&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Event Trigger&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;event_trigger&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1308-1714&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;funktionlog_ddl_command&quot;&gt;Funktion: log_ddl_command()&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Diese Funktion verarbeitet alle DDL-Kommandos außer DROP. Sie nutzt `pg_event_trigger_ddl_commands()` und extrahiert relevante Informationen aus dem DDL-Kontext:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;REPLACE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_command&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;RETURNS&lt;/span&gt; event_trigger
&lt;span class=&quot;kw1&quot;&gt;LANGUAGE&lt;/span&gt; plpgsql
&lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; $$
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt;
  ddl_record RECORD;
&lt;span class=&quot;kw1&quot;&gt;BEGIN&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;FOR&lt;/span&gt; ddl_record &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_event_trigger_ddl_commands&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  LOOP
    &lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
      command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      schema_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      object_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      executed_by&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      strg
    &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
      ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      current_query&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; LOOP;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt;;
$$;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Funktion: log_ddl_command()&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;funktionlog_ddl_command&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1715-2546&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;funktionlog_ddl_drop&quot;&gt;Funktion: log_ddl_drop()&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
DROP-Kommandos werden separat behandelt, da sie über `pg_event_trigger_dropped_objects()` erfasst werden. Der Befehlstyp wird manuell auf `&amp;#039;DROP&amp;#039;` gesetzt:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;REPLACE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;RETURNS&lt;/span&gt; event_trigger
&lt;span class=&quot;kw1&quot;&gt;LANGUAGE&lt;/span&gt; plpgsql
&lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; $$
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt;
  obj RECORD;
&lt;span class=&quot;kw1&quot;&gt;BEGIN&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;FOR&lt;/span&gt; obj &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_event_trigger_dropped_objects&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  LOOP
    &lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
      command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      schema_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      object_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      executed_by
    &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
      &lt;span class=&quot;st0&quot;&gt;&#039;DROP&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
  &lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; LOOP;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt;;
$$;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Funktion: log_ddl_drop()&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;funktionlog_ddl_drop&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;2547-3283&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit6&quot; id=&quot;weitere_triggerpunkte&quot;&gt;Weitere Triggerpunkte&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
PostgreSQL bietet mehrere eingebaute Event-Zeitpunkte, die für erweitertes Logging genutzt werden können:
&lt;/p&gt;
&lt;div class=&quot;table sectionedit7&quot;&gt;&lt;table class=&quot;inline&quot;&gt;
	&lt;thead&gt;
	&lt;tr class=&quot;row0&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; Event-Zeitpunkt &lt;/th&gt;&lt;th class=&quot;col1&quot;&gt; Beschreibung &lt;/th&gt;
	&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tr class=&quot;row1&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; `ddl_command_start` &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; Wird ausgelöst zu Beginn eines DDL-Kommandos. &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row2&quot;&gt;
		&lt;td class=&quot;col0 leftalign&quot;&gt; `ddl_command_end`   &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; Wird ausgelöst nach erfolgreichem Abschluss eines DDL-Kommandos. &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row3&quot;&gt;
		&lt;td class=&quot;col0 leftalign&quot;&gt; `sql_drop`          &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; Wird ausgelöst bei DROP-Operationen. &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row4&quot;&gt;
		&lt;td class=&quot;col0 leftalign&quot;&gt; `table_rewrite`     &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; Wird ausgelöst, wenn eine Tabelle intern neu geschrieben wird. &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;3428-3781&amp;quot;} --&gt;
&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Weitere Triggerpunkte&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;weitere_triggerpunkte&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;3284-3782&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit8&quot; id=&quot;wartungtrigger_aktivieren_deaktivieren&quot;&gt;Wartung: Trigger aktivieren/deaktivieren&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Es handelt sich um &lt;strong&gt;Event Trigger&lt;/strong&gt; (nicht um Row-Level-Trigger auf Tabellen). Nur Rollen mit ausreichenden Rechten (typischerweise &lt;strong&gt;Superuser&lt;/strong&gt; oder entsprechende Konfiguration) dürfen &lt;code&gt;ALTER EVENT TRIGGER&lt;/code&gt; ausführen.
&lt;/p&gt;

&lt;p&gt;
Die Namen können bei Abweichung von diesem Beispiel in &lt;code&gt;pg_event_trigger&lt;/code&gt; nachgeschlagen werden:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; evtname&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; evtenabled&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; evtevent
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_event_trigger
&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; evtname &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;ddl%&#039;&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;
&lt;code&gt;evtenabled&lt;/code&gt;: &lt;code&gt;O&lt;/code&gt; = aktiv (enabled), &lt;code&gt;D&lt;/code&gt; = mit &lt;code&gt;DISABLE&lt;/code&gt; abgeschaltet.
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;co1&quot;&gt;-- beide Audit-Trigger abschalten (z. B. Massenmigration, Wartung)&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_audit_trigger DISABLE;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_drop_audit_trigger DISABLE;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;-- nur einen Abschnitt abschalten (CREATE/ALTER oder DROP)&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_audit_trigger DISABLE;
&lt;span class=&quot;co1&quot;&gt;-- oder nur DROP-Protokollierung:&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_drop_audit_trigger DISABLE;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;-- wieder einschalten (Standardzustand)&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_audit_trigger ENABLE;
&lt;span class=&quot;kw1&quot;&gt;ALTER&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_drop_audit_trigger ENABLE;&lt;/pre&gt;

&lt;p&gt;
Nach &lt;code&gt;DISABLE&lt;/code&gt; werden keine neuen DDL-Einträge mehr geschrieben; bestehende Zeilen in &lt;code&gt;ddl_audit_log&lt;/code&gt; bleiben erhalten. Nach Abschluss der Arbeit wieder &lt;code&gt;ENABLE&lt;/code&gt; setzen.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Wartung: Trigger aktivieren\/deaktivieren&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;wartungtrigger_aktivieren_deaktivieren&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;3783-5044&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit9&quot; id=&quot;stichworte&quot;&gt;Stichworte&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;em&gt;PostgreSQL, DDL, Audit, Event Trigger, pg_event_trigger_ddl_commands, Logging, DISABLE, ENABLE, Wartung&lt;/em&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Stichworte&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;stichworte&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:6,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;5045-&amp;quot;} --&gt;</description>
    </item>
    <item rdf:about="http://wiki.redatek.de/postgres:statistik_und_audit?rev=1777794334&amp;do=diff">
        <dc:format>text/html</dc:format>
        <dc:date>2026-05-03T07:45:34+00:00</dc:date>
        <dc:creator>Anonymous (anonymous@undisclosed.example.com)</dc:creator>
        <title>statistik_und_audit</title>
        <link>http://wiki.redatek.de/postgres:statistik_und_audit?rev=1777794334&amp;do=diff</link>
        <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;postgresql_ddl-audit_setup&quot;&gt;PostgreSQL DDL-Audit Setup&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Dieses Setup dokumentiert alle &lt;strong&gt;strukturverändernden Aktionen (DDL)&lt;/strong&gt; in PostgreSQL, wie z. B. &lt;code&gt;CREATE TABLE&lt;/code&gt;, &lt;code&gt;ALTER FUNCTION&lt;/code&gt;, &lt;code&gt;DROP INDEX&lt;/code&gt; usw.  
Die Änderungen werden automatisch in einer zentralen Audit-Tabelle gespeichert und sind über ein Dashboard oder View auswertbar.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;http://wiki.redatek.de/lib/images/smileys/exclaim.svg&quot; class=&quot;icon smiley&quot; alt=&quot;:!:&quot; /&gt; &lt;strong&gt;Verwandter Artikel:&lt;/strong&gt; Tabellen, Trigger-Funktionen, Event Trigger und &lt;strong&gt;Wartung (DISABLE/ENABLE)&lt;/strong&gt; sind in &lt;a href=&quot;http://wiki.redatek.de/postgres:ddl_logging&quot; class=&quot;wikilink1&quot; title=&quot;postgres:ddl_logging&quot; data-wiki-id=&quot;postgres:ddl_logging&quot;&gt;PostgreSQL DDL Audit Logging&lt;/a&gt; beschrieben (Referenzimplementierung).
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;PostgreSQL DDL-Audit Setup&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;postgresql_ddl-audit_setup&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-540&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;ziel&quot;&gt;Ziel&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
* Nachvollziehbare Dokumentation aller DDL-Änderungen
* Speicherung in einer zentralen Tabelle im Schema &lt;code&gt;public&lt;/code&gt;
* Unterstützung für &lt;code&gt;CREATE&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt;, &lt;code&gt;DROP&lt;/code&gt; und verwandte Befehle
* Trennung von Schema und Objektname für bessere Auswertbarkeit
* Minimale Belastung für produktive Systeme
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Ziel&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;ziel&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;541-862&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;komponenten&quot;&gt;Komponenten&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
* &lt;strong&gt;Audit-Tabelle:&lt;/strong&gt; Speicherung der DDL-Ereignisse
* &lt;strong&gt;Event Trigger:&lt;/strong&gt; Reaktion auf DDL-Befehle
* &lt;strong&gt;Trigger-Prozeduren:&lt;/strong&gt; Extrahieren der Metadaten aus Systemfunktionen
* &lt;strong&gt;Optional: pg_stat_statements:&lt;/strong&gt; Ergänzende Erfassung von DDL-Texten
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Komponenten&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;komponenten&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;863-1132&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;schritt_1audit-tabelle_erstellen&quot;&gt;Schritt 1: Audit-Tabelle erstellen&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;TABLE&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
id SERIAL &lt;span class=&quot;kw1&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
command_tag TEXT&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;             &lt;span class=&quot;co1&quot;&gt;-- z. B. CREATE TABLE, DROP FUNCTION&lt;/span&gt;
object_type TEXT&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;             &lt;span class=&quot;co1&quot;&gt;-- z. B. TABLE, FUNCTION, INDEX&lt;/span&gt;
schema_name TEXT&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;             &lt;span class=&quot;co1&quot;&gt;-- z. B. public&lt;/span&gt;
object_name TEXT&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;             &lt;span class=&quot;co1&quot;&gt;-- z. B. users&lt;/span&gt;
executed_by TEXT &lt;span class=&quot;kw1&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
executed_at &lt;span class=&quot;kw1&quot;&gt;TIMESTAMP&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;CURRENT_TIMESTAMP&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Schritt 1: Audit-Tabelle erstellen&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;schritt_1audit-tabelle_erstellen&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1133-1577&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;schritt_2prozedur_fuer_create_alter&quot;&gt;Schritt 2: Prozedur für CREATE/ALTER&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;REPLACE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_command&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;RETURNS&lt;/span&gt; event_trigger
&lt;span class=&quot;kw1&quot;&gt;LANGUAGE&lt;/span&gt; plpgsql
&lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; $$
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt;
ddl_record RECORD;
&lt;span class=&quot;kw1&quot;&gt;BEGIN&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;FOR&lt;/span&gt; ddl_record &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_event_trigger_ddl_commands&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
LOOP
&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
schema_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
executed_by
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ddl_record&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; LOOP;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt;;
$$;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Schritt 2: Prozedur f\u00fcr CREATE\/ALTER&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;schritt_2prozedur_fuer_create_alter&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;1578-2136&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit6&quot; id=&quot;schritt_3event_trigger_fuer_create_alter&quot;&gt;Schritt 3: Event Trigger für CREATE/ALTER&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_audit_trigger
&lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; ddl_command_end
&lt;span class=&quot;kw1&quot;&gt;EXECUTE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_command&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Schritt 3: Event Trigger f\u00fcr CREATE\/ALTER&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;schritt_3event_trigger_fuer_create_alter&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;2137-2313&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit7&quot; id=&quot;schritt_4prozedur_fuer_drop-aktionen&quot;&gt;Schritt 4: Prozedur für DROP-Aktionen&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;REPLACE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;RETURNS&lt;/span&gt; event_trigger
&lt;span class=&quot;kw1&quot;&gt;LANGUAGE&lt;/span&gt; plpgsql
&lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; $$
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt;
obj RECORD;
&lt;span class=&quot;kw1&quot;&gt;BEGIN&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;FOR&lt;/span&gt; obj &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_event_trigger_dropped_objects&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
LOOP
&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
schema_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
executed_by
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
&lt;span class=&quot;st0&quot;&gt;&#039;DROP&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
split_part&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;obj&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;object_identity&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;.&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;CURRENT_USER&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; LOOP;
&lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt;;
$$;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Schritt 4: Prozedur f\u00fcr DROP-Aktionen&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;schritt_4prozedur_fuer_drop-aktionen&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;2314-2822&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit8&quot; id=&quot;schritt_5event_trigger_fuer_drop-aktionen&quot;&gt;Schritt 5: Event Trigger für DROP-Aktionen&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; EVENT &lt;span class=&quot;kw1&quot;&gt;TRIGGER&lt;/span&gt; ddl_drop_audit_trigger
&lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; sql_drop
&lt;span class=&quot;kw1&quot;&gt;EXECUTE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FUNCTION&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;log_ddl_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Schritt 5: Event Trigger f\u00fcr DROP-Aktionen&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;schritt_5event_trigger_fuer_drop-aktionen&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;2823-2995&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit9&quot; id=&quot;wartungtrigger_aktivieren_deaktivieren&quot;&gt;Wartung: Trigger aktivieren/deaktivieren&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;img src=&quot;http://wiki.redatek.de/lib/images/smileys/exclaim.svg&quot; class=&quot;icon smiley&quot; alt=&quot;:!:&quot; /&gt; Befehle und Erläuterung: &lt;a href=&quot;http://wiki.redatek.de/postgres:ddl_logging&quot; class=&quot;wikilink1&quot; title=&quot;postgres:ddl_logging&quot; data-wiki-id=&quot;postgres:ddl_logging&quot;&gt;PostgreSQL DDL Audit Logging&lt;/a&gt; — Abschnitt &lt;strong&gt;Wartung: Trigger aktivieren/deaktivieren&lt;/strong&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Wartung: Trigger aktivieren\/deaktivieren&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;wartungtrigger_aktivieren_deaktivieren&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;2996-3194&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit10&quot; id=&quot;beispielddl-aktion_und_auswertung&quot;&gt;Beispiel: DDL-Aktion und Auswertung&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;\&lt;span class=&quot;co1&quot;&gt;-- Beispielaktion&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;TABLE&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;audit_test &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
id SERIAL &lt;span class=&quot;kw1&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
name TEXT
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class=&quot;kw1&quot;&gt;DROP&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;TABLE&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;audit_test;
&amp;nbsp;
\&lt;span class=&quot;co1&quot;&gt;-- Auswertung&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; executed_at &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Beispiel: DDL-Aktion und Auswertung&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;beispielddl-aktion_und_auswertung&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;3195-3460&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit11&quot; id=&quot;optionalview_fuer_dashboard&quot;&gt;Optional: View für Dashboard&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;VIEW&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_summary &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt;
executed_at::&lt;span class=&quot;kw1&quot;&gt;DATE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; datum&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
schema_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_name&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
command_tag&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
object_type&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
executed_by
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;ddl_audit_log
&lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; executed_at &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Optional: View f\u00fcr Dashboard&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;optionalview_fuer_dashboard&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:6,&amp;quot;secid&amp;quot;:11,&amp;quot;range&amp;quot;:&amp;quot;3461-3715&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit12&quot; id=&quot;erweiterungpg_stat_statements&quot;&gt;Erweiterung: pg_stat_statements&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Die PostgreSQL-Erweiterung &lt;code&gt;pg_stat_statements&lt;/code&gt; kann ergänzend verwendet werden, um &lt;strong&gt;vollständige DDL-Befehle&lt;/strong&gt; (inkl. Spaltennamen) zu erfassen, die über Event Trigger nicht verfügbar sind.
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; query&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; calls&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; userid&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; dbid&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; queryid&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; total_time
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pg_stat_statements
&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; query &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;ALTER TABLE%&#039;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; query \~\&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;ADD COLUMN|DROP COLUMN|RENAME COLUMN&#039;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; total_time &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;
oder eben selektiv mit lesbarem User und Datenbanknamen:
&lt;/p&gt;
&lt;pre class=&quot;code sql&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; a&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;rolname&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;datname&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;c&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;query
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; public&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;pg_stat_statements c&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; pg_roles a&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; pg_database b
&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; a&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;oid &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;userid &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; b&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;oid &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; c&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;dbid
&lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; c&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;query &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&#039;ALTER%&#039;&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;
Hinweis:
&lt;/p&gt;

&lt;p&gt;
* Die Erweiterung speichert normierte SQL-Befehle
* Die Statistik wird nicht sofort aktualisiert
* Für produktive Systeme mit hoher Last kann die Kombination mit Event Triggern zu Performance-Einbußen führen
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Erweiterung: pg_stat_statements&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;erweiterungpg_stat_statements&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:7,&amp;quot;secid&amp;quot;:12,&amp;quot;range&amp;quot;:&amp;quot;3716-4635&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit13&quot; id=&quot;hinweise&quot;&gt;Hinweise&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
* Die Spalte &lt;code&gt;ddl&lt;/code&gt; wurde entfernt, da der Typ &lt;code&gt;pg_ddl_command&lt;/code&gt; nicht direkt gespeichert werden kann.
* Spaltenänderungen (z. B. &lt;code&gt;ADD COLUMN&lt;/code&gt;) enthalten keine Spaltennamen über Event Trigger.
* Die Lösung ist leichtgewichtig und für produktive Systeme geeignet.
* DDL-Audit vorübergehend aus: &lt;a href=&quot;http://wiki.redatek.de/postgres:ddl_logging&quot; class=&quot;wikilink1&quot; title=&quot;postgres:ddl_logging&quot; data-wiki-id=&quot;postgres:ddl_logging&quot;&gt;PostgreSQL DDL Audit Logging&lt;/a&gt;, Abschnitt &lt;strong&gt;Wartung: Trigger aktivieren/deaktivieren&lt;/strong&gt; (&lt;code&gt;ALTER EVENT TRIGGER … DISABLE&lt;/code&gt; / &lt;code&gt;ENABLE&lt;/code&gt;).
* Event Trigger und Tabellen-Trigger sind verschiedene Mechanismen — siehe folgender Unterabschnitt.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Hinweise&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;hinweise&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:13,&amp;quot;range&amp;quot;:&amp;quot;4636-5228&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit14&quot; id=&quot;event_trigger_versus_tabellen-trigger&quot;&gt;Event Trigger versus Tabellen-Trigger&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;div class=&quot;table sectionedit15&quot;&gt;&lt;table class=&quot;inline&quot;&gt;
	&lt;thead&gt;
	&lt;tr class=&quot;row0&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; Aspekt &lt;/th&gt;&lt;th class=&quot;col1&quot;&gt; Event Trigger (dieses DDL-Audit) &lt;/th&gt;&lt;th class=&quot;col2&quot;&gt; Tabellen-Trigger &lt;/th&gt;
	&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tr class=&quot;row1&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; Zweck &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; Reaktion auf &lt;strong&gt;DDL&lt;/strong&gt; (&lt;code&gt;CREATE TABLE&lt;/code&gt;, &lt;code&gt;DROP&lt;/code&gt;, …) auf Datenbankebene &lt;/td&gt;&lt;td class=&quot;col2&quot;&gt; Reaktion auf &lt;strong&gt;Datenänderungen&lt;/strong&gt; in einer Tabelle: &lt;code&gt;INSERT&lt;/code&gt; / &lt;code&gt;UPDATE&lt;/code&gt; / &lt;code&gt;DELETE&lt;/code&gt;, oft &lt;code&gt;FOR EACH ROW&lt;/code&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row2&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; Anlage &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; &lt;code&gt;CREATE EVENT TRIGGER …&lt;/code&gt; &lt;/td&gt;&lt;td class=&quot;col2&quot;&gt; &lt;code&gt;CREATE TRIGGER … ON eine_tabelle …&lt;/code&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row3&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; Abschalten (Beispiel) &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; &lt;code&gt;ALTER EVENT TRIGGER … DISABLE&lt;/code&gt; / &lt;code&gt;… ENABLE&lt;/code&gt; &lt;/td&gt;&lt;td class=&quot;col2&quot;&gt; z. B. &lt;code&gt;ALTER TABLE … DISABLE TRIGGER …&lt;/code&gt; &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;secid&amp;quot;:15,&amp;quot;range&amp;quot;:&amp;quot;5278-5759&amp;quot;} --&gt;
&lt;p&gt;
Zum &lt;strong&gt;vorübergehenden Abschalten dieses DDL-Audits&lt;/strong&gt; werden nur &lt;strong&gt;Event Trigger&lt;/strong&gt; mit &lt;code&gt;ALTER EVENT TRIGGER …&lt;/code&gt; gesteuert. &lt;code&gt;ALTER TABLE … DISABLE TRIGGER …&lt;/code&gt; betrifft &lt;strong&gt;Tabellen-Trigger&lt;/strong&gt; auf einer konkreten Tabelle und hat mit diesem DDL-Protokoll &lt;strong&gt;nichts&lt;/strong&gt; zu tun.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Event Trigger versus Tabellen-Trigger&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;event_trigger_versus_tabellen-trigger&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:14,&amp;quot;range&amp;quot;:&amp;quot;5229-6037&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit16&quot; id=&quot;erweiterungen_moeglich&quot;&gt;Erweiterungen möglich&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
* Filterung nach Objektarten oder Benutzer
* Integration mit Git zur Versionskontrolle
* Visualisierung der Änderungen über Dashboards
* Benachrichtigung bei kritischen Änderungen (z. B. DROP TABLE)
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Erweiterungen m\u00f6glich&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;erweiterungen_moeglich&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:16,&amp;quot;range&amp;quot;:&amp;quot;6038-6278&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit17&quot; id=&quot;bemerkung&quot;&gt;Bemerkung&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;img src=&quot;http://wiki.redatek.de/lib/images/smileys/exclaim.svg&quot; class=&quot;icon smiley&quot; alt=&quot;:!:&quot; /&gt; Für mich ist das Standard Vorgehen meist unbrauchbar, da pg_stat_statements wie auch pgaudit nicht das Objekt selbst aufzeichnet. Ich schreibe meine eigene Triggerfunction — dokumentiert in &lt;a href=&quot;http://wiki.redatek.de/postgres:ddl_logging&quot; class=&quot;wikilink1&quot; title=&quot;postgres:ddl_logging&quot; data-wiki-id=&quot;postgres:ddl_logging&quot;&gt;PostgreSQL DDL Audit Logging&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Bemerkung&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;bemerkung&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:17,&amp;quot;range&amp;quot;:&amp;quot;6279-6554&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit18&quot; id=&quot;stichworte&quot;&gt;Stichworte&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;em&gt;PostgreSQL, DDL, Audit, Event Trigger, pg_stat_statements, Dashboard&lt;/em&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Stichworte&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;stichworte&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:18,&amp;quot;range&amp;quot;:&amp;quot;6555-&amp;quot;} --&gt;</description>
    </item>
</rdf:RDF>
