Tom Lane  committed cd3413e

Disable event triggers in standalone mode.

Per discussion, this seems necessary to allow recovery from broken event
triggers, or broken indexes on pg_event_trigger.

Dimitri Fontaine

  • Participants
  • Parent commits b19e425
  • Branches jsonapi

Comments (0)

Files changed (2)

File doc/src/sgml/ref/create_event_trigger.sgml

-   To create a trigger on a event, the user must be superuser.
+   Only superusers can create event triggers.
+  </para>
+  <para>
+   Event triggers are disabled in single-user mode (see <xref
+   linkend="app-postgres">).  If an erroneous event trigger disables the
+   database so much that you can't even drop the trigger, restart in
+   single-user mode and you'll be able to do that.
-   Forbid the execution of any <link linkend="ddl">ddl</link> command:
+   Forbid the execution of any <link linkend="ddl">DDL</link> command:
 CREATE OR REPLACE FUNCTION abort_any_command()

File src/backend/commands/event_trigger.c

 	EventTriggerData	trigdata;
+	 * Event Triggers are completely disabled in standalone mode.  There are
+	 * (at least) two reasons for this:
+	 *
+	 * 1. A sufficiently broken event trigger might not only render the
+	 * database unusable, but prevent disabling itself to fix the situation.
+	 * In this scenario, restarting in standalone mode provides an escape
+	 * hatch.
+	 *
+	 * 2. BuildEventTriggerCache relies on systable_beginscan_ordered, and
+	 * therefore will malfunction if pg_event_trigger's indexes are damaged.
+	 * To allow recovery from a damaged index, we need some operating mode
+	 * wherein event triggers are disabled.  (Or we could implement
+	 * heapscan-and-sort logic for that case, but having disaster recovery
+	 * scenarios depend on code that's otherwise untested isn't appetizing.)
+	 */
+	if (!IsUnderPostmaster)
+		return;
+	/*
 	 * We want the list of command tags for which this procedure is actually
 	 * invoked to match up exactly with the list that CREATE EVENT TRIGGER
 	 * accepts.  This debugging cross-check will throw an error if this