Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7750fef

Browse files
Add GUC for temporarily disabling event triggers
In order to troubleshoot misbehaving or buggy event triggers, the documented advice is to enter single-user mode. In an attempt to reduce the number of situations where single-user mode is required (or even recommended) for non-extraordinary maintenance, this GUC allows to temporarily suspend event triggers. This was originally extracted from a larger patchset which aimed at supporting event triggers on login events. Reviewed-by: Ted Yu <yuzhihong@gmail.com> Reviewed-by: Mikhail Gribkov <youzhick@gmail.com> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Reviewed-by: Michael Paquier <michael@paquier.xyz Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://postgr.es/m/9140106E-F9BF-4D85-8FC8-F2D3C094A6D9@yesql.se Discussion: https://postgr.es/m/0d46d29f-4558-3af9-9c85-7774e14a7709@postgrespro.ru
1 parent f19669f commit 7750fef

File tree

8 files changed

+98
-10
lines changed

8 files changed

+98
-10
lines changed

doc/src/sgml/config.sgml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9425,6 +9425,25 @@ SET XML OPTION { DOCUMENT | CONTENT };
94259425
</listitem>
94269426
</varlistentry>
94279427

9428+
<varlistentry id="guc-event-triggers" xreflabel="event_triggers">
9429+
<term><varname>event_triggers</varname> (<type>boolean</type>)
9430+
<indexterm>
9431+
<primary><varname>event_triggers</varname></primary>
9432+
<secondary>configuration parameter</secondary>
9433+
</indexterm>
9434+
</term>
9435+
<listitem>
9436+
<para>
9437+
Allow temporarily disabling execution of event triggers in order to
9438+
troubleshoot and repair faulty event triggers. All event triggers will
9439+
be disabled by setting it to <literal>false</literal>. Setting the value
9440+
to <literal>true</literal> allows all event triggers to fire, this
9441+
is the default value. Only superusers and users with the appropriate
9442+
<literal>SET</literal> privilege can change this setting.
9443+
</para>
9444+
</listitem>
9445+
</varlistentry>
9446+
94289447
</variablelist>
94299448
</sect2>
94309449
<sect2 id="runtime-config-client-format">

doc/src/sgml/ref/create_event_trigger.sgml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,12 @@ CREATE EVENT TRIGGER <replaceable class="parameter">name</replaceable>
121121

122122
<para>
123123
Event triggers are disabled in single-user mode (see <xref
124-
linkend="app-postgres"/>). If an erroneous event trigger disables the
125-
database so much that you can't even drop the trigger, restart in
126-
single-user mode and you'll be able to do that.
124+
linkend="app-postgres"/>) as well as when
125+
<xref linkend="guc-event-triggers"/> is set to <literal>false</literal>.
126+
If an erroneous event trigger disables the database so much that you can't
127+
even drop the trigger, restart with <xref linkend="guc-event-triggers"/>
128+
set to <literal>false</literal> to temporarily disable event triggers, or
129+
in single-user mode, and you'll be able to do that.
127130
</para>
128131
</refsect1>
129132

src/backend/commands/event_trigger.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ typedef struct EventTriggerQueryState
7272

7373
static EventTriggerQueryState *currentEventTriggerState = NULL;
7474

75+
/* GUC parameter */
76+
bool event_triggers = true;
77+
7578
/* Support for dropped objects */
7679
typedef struct SQLDropObject
7780
{
@@ -657,8 +660,11 @@ EventTriggerDDLCommandStart(Node *parsetree)
657660
* wherein event triggers are disabled. (Or we could implement
658661
* heapscan-and-sort logic for that case, but having disaster recovery
659662
* scenarios depend on code that's otherwise untested isn't appetizing.)
663+
*
664+
* Additionally, event triggers can be disabled with a superuser-only GUC
665+
* to make fixing database easier as per 1 above.
660666
*/
661-
if (!IsUnderPostmaster)
667+
if (!IsUnderPostmaster || !event_triggers)
662668
return;
663669

664670
runlist = EventTriggerCommonSetup(parsetree,
@@ -692,9 +698,9 @@ EventTriggerDDLCommandEnd(Node *parsetree)
692698

693699
/*
694700
* See EventTriggerDDLCommandStart for a discussion about why event
695-
* triggers are disabled in single user mode.
701+
* triggers are disabled in single user mode or via GUC.
696702
*/
697-
if (!IsUnderPostmaster)
703+
if (!IsUnderPostmaster || !event_triggers)
698704
return;
699705

700706
/*
@@ -740,9 +746,9 @@ EventTriggerSQLDrop(Node *parsetree)
740746

741747
/*
742748
* See EventTriggerDDLCommandStart for a discussion about why event
743-
* triggers are disabled in single user mode.
749+
* triggers are disabled in single user mode or via a GUC.
744750
*/
745-
if (!IsUnderPostmaster)
751+
if (!IsUnderPostmaster || !event_triggers)
746752
return;
747753

748754
/*
@@ -811,9 +817,9 @@ EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason)
811817

812818
/*
813819
* See EventTriggerDDLCommandStart for a discussion about why event
814-
* triggers are disabled in single user mode.
820+
* triggers are disabled in single user mode or via a GUC.
815821
*/
816-
if (!IsUnderPostmaster)
822+
if (!IsUnderPostmaster || !event_triggers)
817823
return;
818824

819825
/*

src/backend/utils/misc/guc_tables.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "catalog/namespace.h"
3838
#include "catalog/storage.h"
3939
#include "commands/async.h"
40+
#include "commands/event_trigger.h"
4041
#include "commands/tablespace.h"
4142
#include "commands/trigger.h"
4243
#include "commands/user.h"
@@ -2000,6 +2001,16 @@ struct config_bool ConfigureNamesBool[] =
20002001
NULL, NULL, NULL
20012002
},
20022003

2004+
{
2005+
{"event_triggers", PGC_SUSET, CLIENT_CONN_STATEMENT,
2006+
gettext_noop("Enables event triggers."),
2007+
gettext_noop("When enabled, event triggers will fire for all applicable statements."),
2008+
},
2009+
&event_triggers,
2010+
true,
2011+
NULL, NULL, NULL
2012+
},
2013+
20032014
/* End-of-list marker */
20042015
{
20052016
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@
706706
#xmloption = 'content'
707707
#gin_pending_list_limit = 4MB
708708
#createrole_self_grant = '' # set and/or inherit
709+
#event_triggers = on
709710

710711
# - Locale and Formatting -
711712

src/include/commands/event_trigger.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ typedef struct EventTriggerData
2929
CommandTag tag;
3030
} EventTriggerData;
3131

32+
extern PGDLLIMPORT bool event_triggers;
33+
3234
#define AT_REWRITE_ALTER_PERSISTENCE 0x01
3335
#define AT_REWRITE_DEFAULT_VAL 0x02
3436
#define AT_REWRITE_COLUMN_REWRITE 0x04

src/test/regress/expected/event_trigger.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,25 @@ SELECT
616616
DROP EVENT TRIGGER start_rls_command;
617617
DROP EVENT TRIGGER end_rls_command;
618618
DROP EVENT TRIGGER sql_drop_command;
619+
-- Check the GUC for disabling event triggers
620+
CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
621+
LANGUAGE plpgsql AS $$
622+
DECLARE
623+
obj record;
624+
BEGIN
625+
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
626+
LOOP
627+
RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
628+
END LOOP;
629+
END;
630+
$$;
631+
CREATE EVENT TRIGGER test_event_trigger_guc
632+
ON sql_drop
633+
WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
634+
SET event_triggers = 'on';
635+
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
636+
DROP POLICY pguc ON event_trigger_test;
637+
NOTICE: DROP POLICY dropped policy
638+
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
639+
SET event_triggers = 'off';
640+
DROP POLICY pguc ON event_trigger_test;

src/test/regress/sql/event_trigger.sql

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,27 @@ SELECT
471471
DROP EVENT TRIGGER start_rls_command;
472472
DROP EVENT TRIGGER end_rls_command;
473473
DROP EVENT TRIGGER sql_drop_command;
474+
475+
-- Check the GUC for disabling event triggers
476+
CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
477+
LANGUAGE plpgsql AS $$
478+
DECLARE
479+
obj record;
480+
BEGIN
481+
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
482+
LOOP
483+
RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
484+
END LOOP;
485+
END;
486+
$$;
487+
CREATE EVENT TRIGGER test_event_trigger_guc
488+
ON sql_drop
489+
WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
490+
491+
SET event_triggers = 'on';
492+
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
493+
DROP POLICY pguc ON event_trigger_test;
494+
495+
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
496+
SET event_triggers = 'off';
497+
DROP POLICY pguc ON event_trigger_test;

0 commit comments

Comments
 (0)