- new GUC in "Statement Behaviour" section, notify_duplicate_removal (default true)
Initial discussion in this thread: http://www.postgresql.org/message-id/CAP_rwwmpzk9=sbjrztod05bdctyc43wnknu_m37dygvl4sa...@mail.gmail.com Rationale: for some legitimate use cases, duplicate removal is not required, and it gets O(N^2) cost on large COPY/ insert transactions.
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 392eb70..9fb5504 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -6095,6 +6095,24 @@ SET XML OPTION { DOCUMENT | CONTENT }; </listitem> </varlistentry> + <varlistentry id="guc-notify-duplicate-removal" xreflabel="notify_duplicate_removal"> + <term><varname>notify_duplicate_removal</varname> (<type>bool</type>) + <indexterm> + <primary><varname>notify_duplicate_removal</> configuration parameter</primary> + </indexterm> + </term> + <listitem> + <para> + Try to remove duplicate messages while processing NOTIFY. When + <literal>on</> (the default), the server will avoid duplicate messages + (with same channel and payload). Setting this variable to + <literal>off</> can increase performance in some situations - at the + cost of having duplicate messages in NOTIFY queue. See <xref + linkend="SQL-NOTIFY"> for more information. + </para> + </listitem> + </varlistentry> + </variablelist> </sect2> <sect2 id="runtime-config-client-format"> diff --git a/doc/src/sgml/ref/notify.sgml b/doc/src/sgml/ref/notify.sgml index 4dd5608..86a9bed 100644 --- a/doc/src/sgml/ref/notify.sgml +++ b/doc/src/sgml/ref/notify.sgml @@ -95,16 +95,17 @@ NOTIFY <replaceable class="PARAMETER">channel</replaceable> [ , <replaceable cla <para> If the same channel name is signaled multiple times from the same - transaction with identical payload strings, the - database server can decide to deliver a single notification only. - On the other hand, notifications with distinct payload strings will - always be delivered as distinct notifications. Similarly, notifications from - different transactions will never get folded into one notification. - Except for dropping later instances of duplicate notifications, + transaction with identical payload strings, and + <varname>notify_duplicate_removal</> is set to true, the database server + can decide to deliver a single notification only. On the other hand, + notifications with distinct payload strings will always be delivered as + distinct notifications. Similarly, notifications from different + transactions will never get folded into one notification. Except for + dropping later instances of duplicate notifications, <command>NOTIFY</command> guarantees that notifications from the same transaction get delivered in the order they were sent. It is also - guaranteed that messages from different transactions are delivered in - the order in which the transactions committed. + guaranteed that messages from different transactions are delivered in the + order in which the transactions committed. </para> <para> diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index c39ac3a..a7bc9f1 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -364,8 +364,9 @@ static bool amRegisteredListener = false; /* has this backend sent notifications in the current transaction? */ static bool backendHasSentNotifications = false; -/* GUC parameter */ +/* GUC parameters */ bool Trace_notify = false; +bool notify_duplicate_removal = true; /* local function prototypes */ static bool asyncQueuePagePrecedes(int p, int q); @@ -570,9 +571,12 @@ Async_Notify(const char *channel, const char *payload) errmsg("payload string too long"))); } - /* no point in making duplicate entries in the list ... */ - if (AsyncExistsPendingNotify(channel, payload)) - return; + if (notify_duplicate_removal) + { + /* check for duplicate entries in the list */ + if (AsyncExistsPendingNotify(channel, payload)) + return; + } /* * The notification list needs to live until end of transaction, so store diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 83b8388..b737c29 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1617,6 +1617,15 @@ static struct config_bool ConfigureNamesBool[] = false, NULL, NULL, NULL }, + { + {"notify_duplicate_removal", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Remove duplicate messages during NOTIFY."), + NULL + }, + ¬ify_duplicate_removal, + true, + NULL, NULL, NULL + }, /* End-of-list marker */ { diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 029114f..2831c1b 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -536,6 +536,7 @@ #xmloption = 'content' #gin_fuzzy_search_limit = 0 #gin_pending_list_limit = 4MB +#notify_duplicate_removal = on # - Locale and Formatting - diff --git a/src/include/commands/async.h b/src/include/commands/async.h index b4c13fa..c572691 100644 --- a/src/include/commands/async.h +++ b/src/include/commands/async.h @@ -23,6 +23,7 @@ #define NUM_ASYNC_BUFFERS 8 extern bool Trace_notify; +extern bool notify_duplicate_removal; extern volatile sig_atomic_t notifyInterruptPending; extern Size AsyncShmemSize(void);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers