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
This commit is contained in:
parent
f19669fed3
commit
7750fefdb2
@ -9425,6 +9425,25 @@ SET XML OPTION { DOCUMENT | CONTENT };
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="guc-event-triggers" xreflabel="event_triggers">
|
||||
<term><varname>event_triggers</varname> (<type>boolean</type>)
|
||||
<indexterm>
|
||||
<primary><varname>event_triggers</varname></primary>
|
||||
<secondary>configuration parameter</secondary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Allow temporarily disabling execution of event triggers in order to
|
||||
troubleshoot and repair faulty event triggers. All event triggers will
|
||||
be disabled by setting it to <literal>false</literal>. Setting the value
|
||||
to <literal>true</literal> allows all event triggers to fire, this
|
||||
is the default value. Only superusers and users with the appropriate
|
||||
<literal>SET</literal> privilege can change this setting.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="runtime-config-client-format">
|
||||
|
@ -121,9 +121,12 @@ CREATE EVENT TRIGGER <replaceable class="parameter">name</replaceable>
|
||||
|
||||
<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.
|
||||
linkend="app-postgres"/>) as well as when
|
||||
<xref linkend="guc-event-triggers"/> is set to <literal>false</literal>.
|
||||
If an erroneous event trigger disables the database so much that you can't
|
||||
even drop the trigger, restart with <xref linkend="guc-event-triggers"/>
|
||||
set to <literal>false</literal> to temporarily disable event triggers, or
|
||||
in single-user mode, and you'll be able to do that.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
@ -72,6 +72,9 @@ typedef struct EventTriggerQueryState
|
||||
|
||||
static EventTriggerQueryState *currentEventTriggerState = NULL;
|
||||
|
||||
/* GUC parameter */
|
||||
bool event_triggers = true;
|
||||
|
||||
/* Support for dropped objects */
|
||||
typedef struct SQLDropObject
|
||||
{
|
||||
@ -657,8 +660,11 @@ EventTriggerDDLCommandStart(Node *parsetree)
|
||||
* 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.)
|
||||
*
|
||||
* Additionally, event triggers can be disabled with a superuser-only GUC
|
||||
* to make fixing database easier as per 1 above.
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
if (!IsUnderPostmaster || !event_triggers)
|
||||
return;
|
||||
|
||||
runlist = EventTriggerCommonSetup(parsetree,
|
||||
@ -692,9 +698,9 @@ EventTriggerDDLCommandEnd(Node *parsetree)
|
||||
|
||||
/*
|
||||
* See EventTriggerDDLCommandStart for a discussion about why event
|
||||
* triggers are disabled in single user mode.
|
||||
* triggers are disabled in single user mode or via GUC.
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
if (!IsUnderPostmaster || !event_triggers)
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -740,9 +746,9 @@ EventTriggerSQLDrop(Node *parsetree)
|
||||
|
||||
/*
|
||||
* See EventTriggerDDLCommandStart for a discussion about why event
|
||||
* triggers are disabled in single user mode.
|
||||
* triggers are disabled in single user mode or via a GUC.
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
if (!IsUnderPostmaster || !event_triggers)
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -811,9 +817,9 @@ EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason)
|
||||
|
||||
/*
|
||||
* See EventTriggerDDLCommandStart for a discussion about why event
|
||||
* triggers are disabled in single user mode.
|
||||
* triggers are disabled in single user mode or via a GUC.
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
if (!IsUnderPostmaster || !event_triggers)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/storage.h"
|
||||
#include "commands/async.h"
|
||||
#include "commands/event_trigger.h"
|
||||
#include "commands/tablespace.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "commands/user.h"
|
||||
@ -2000,6 +2001,16 @@ struct config_bool ConfigureNamesBool[] =
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
{"event_triggers", PGC_SUSET, CLIENT_CONN_STATEMENT,
|
||||
gettext_noop("Enables event triggers."),
|
||||
gettext_noop("When enabled, event triggers will fire for all applicable statements."),
|
||||
},
|
||||
&event_triggers,
|
||||
true,
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
|
||||
/* End-of-list marker */
|
||||
{
|
||||
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
|
||||
|
@ -706,6 +706,7 @@
|
||||
#xmloption = 'content'
|
||||
#gin_pending_list_limit = 4MB
|
||||
#createrole_self_grant = '' # set and/or inherit
|
||||
#event_triggers = on
|
||||
|
||||
# - Locale and Formatting -
|
||||
|
||||
|
@ -29,6 +29,8 @@ typedef struct EventTriggerData
|
||||
CommandTag tag;
|
||||
} EventTriggerData;
|
||||
|
||||
extern PGDLLIMPORT bool event_triggers;
|
||||
|
||||
#define AT_REWRITE_ALTER_PERSISTENCE 0x01
|
||||
#define AT_REWRITE_DEFAULT_VAL 0x02
|
||||
#define AT_REWRITE_COLUMN_REWRITE 0x04
|
||||
|
@ -616,3 +616,25 @@ SELECT
|
||||
DROP EVENT TRIGGER start_rls_command;
|
||||
DROP EVENT TRIGGER end_rls_command;
|
||||
DROP EVENT TRIGGER sql_drop_command;
|
||||
-- Check the GUC for disabling event triggers
|
||||
CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
obj record;
|
||||
BEGIN
|
||||
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
|
||||
LOOP
|
||||
RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
CREATE EVENT TRIGGER test_event_trigger_guc
|
||||
ON sql_drop
|
||||
WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
|
||||
SET event_triggers = 'on';
|
||||
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
|
||||
DROP POLICY pguc ON event_trigger_test;
|
||||
NOTICE: DROP POLICY dropped policy
|
||||
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
|
||||
SET event_triggers = 'off';
|
||||
DROP POLICY pguc ON event_trigger_test;
|
||||
|
@ -471,3 +471,27 @@ SELECT
|
||||
DROP EVENT TRIGGER start_rls_command;
|
||||
DROP EVENT TRIGGER end_rls_command;
|
||||
DROP EVENT TRIGGER sql_drop_command;
|
||||
|
||||
-- Check the GUC for disabling event triggers
|
||||
CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
obj record;
|
||||
BEGIN
|
||||
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
|
||||
LOOP
|
||||
RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
CREATE EVENT TRIGGER test_event_trigger_guc
|
||||
ON sql_drop
|
||||
WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
|
||||
|
||||
SET event_triggers = 'on';
|
||||
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
|
||||
DROP POLICY pguc ON event_trigger_test;
|
||||
|
||||
CREATE POLICY pguc ON event_trigger_test USING (FALSE);
|
||||
SET event_triggers = 'off';
|
||||
DROP POLICY pguc ON event_trigger_test;
|
||||
|
Loading…
x
Reference in New Issue
Block a user