Re: Listen / Notify - what to do when the queue is full

From: Joachim Wieland <joe(at)mcknight(dot)de>
To: Greg Smith <greg(at)2ndquadrant(dot)com>
Cc: Jeff Davis <pgsql(at)j-davis(dot)com>, Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, "Florian G(dot) Pflug" <fgp(at)phlo(dot)org>, Josh Berkus <josh(at)agliodbs(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: Listen / Notify - what to do when the queue is full
Date: 2009-12-09 10:43:19
Message-ID: dc7b844e0912090243m779fb910jd3ef3cc60f5d49dd@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Mon, Dec 7, 2009 at 5:38 AM, Greg Smith <greg(at)2ndquadrant(dot)com> wrote:
> JI'm going to mark this one "returned with feedback", and I
> do hope that work continues on this patch so it's early in the queue for the
> final CommitFest for this version.  It seems like it just needs a bit more
> time to let the design mature and get the kinks worked out and it could turn
> into a useful feature--I know I've wanted NOTIFY with a payload for a years.

I am perfectly fine with postponing the patch to the next commitfest. To get
some more feedback and to allow everyone to play with it, I am attaching the
latest version of the patch.

What has changed:

Transactional processing is now hopefully correct:

Examples:

Backend 1: Backend 2:

transaction starts
NOTIFY foo;
commit starts
transaction starts
LISTEN foo;
commit starts
commit to clog
commit to clog

=> Backend 2 will receive Backend 1's notification.

Backend 1: Backend 2:

transaction starts
NOTIFY foo;
commit starts
transaction starts
UNLISTEN foo;
commit starts
commit to clog
commit to clog

=> Backend 2 will not receive Backend 1's notification.

This is done by introducing an additional "AsyncCommitOrderLock". It is grabbed
exclusively from transactions that execute LISTEN / UNLISTEN and in shared mode
for transactions that executed NOTIFY only. LISTEN/UNLISTEN transactions then
register the XIDs of the NOTIFYing transactions that are about to commit
at the same time in order to later find out which notifications are visible and
which ones are not.

If the queue is full, any other transaction that is trying to place a
notification to the queue is rolled back! This is basically a consequence of
the former. There are two warnings that will show up in the log once the queue
is more than 50% full and another one if it is more than 75% full. The biggest
threat to run into a full queue are probably backends that are LISTENing and
are idle in transaction.

I have added a function pg_listening() which just contains the names of the
channels that a backend is listening to.

I especially invite people who know more about the transactional stuff than I
do to take a close look at what I have done regarding notification visibility.

One open question regarding the payload is if we need to limit it to ASCII to
not risk conversion issues between different backend character sets?

The second open issue is what we should do regarding 2PC. These options have
been brought up so far:

1) allow NOTIFY in 2PC but it can happen that the transaction needs to be
rolled back if the queue is full
2) disallow NOTIFY in 2PC alltogether
3) put notifications to the queue on PREPARE TRANSACTION and make backends not
advance their pointers further than those notifications but wait for the
2PC transaction to commit. 2PC transactions would never fail but you
effectively stop the notification system until the 2PC transaction commits.

Comments?

Best regards,
Joachim

Attachment Content-Type Size
listennotify.6.diff text/x-diff 92.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2009-12-09 11:49:52 Re: Adding support for SE-Linux security
Previous Message Martin Pihlak 2009-12-09 09:28:28 Re: What happened to pl/proxy and FDW?