Thread
Commits
-
Disallow LISTEN in background workers.
- e06cc024bd33 13.5 landed
- d84d62b6225b 14.0 landed
- 1316be28664f 15.0 landed
-
Send NOTIFY signals during CommitTransaction.
- 63f28776cb9f 13.5 landed
- 2e4eae87d02f 15.0 landed
- 0eff10a00844 14.0 landed
-
Make some efficiency improvements in LISTEN/NOTIFY.
- 51004c7172b5 13.0 cited
-
BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
The Post Office <noreply@postgresql.org> — 2018-07-24T12:13:34Z
The following bug has been logged on the website: Bug reference: 15293 Logged by: Michael Powers Email address: michael.paul.powers@gmail.com PostgreSQL version: 10.4 Operating system: Ubuntu 18.04 Desktop x64 - Linux 4.15.0-29-generic Description: When using logical replication a stored procedure executed on the replica is unable to use NOTIFY to send messages to other listeners. The stored procedure does execute as expected but the pg_notify() doesn't appear to have any effect. If an insert is run on the replica side the trigger executes the stored procedure as expected and the NOTIFY correctly notifies listeners. Steps to Reproduce: Set up Master: CREATE TABLE test (id SERIAL PRIMARY KEY, msg TEXT NOT NULL); CREATE PUBLICATION testpub FOR TABLE test; Set up Replica: CREATE TABLE test (id SERIAL PRIMARY KEY, msg TEXT NOT NULL); CREATE SUBSCRIPTION testsub CONNECTION 'host=192.168.0.136 user=test password=test' PUBLICATION testpub; CREATE OR REPLACE FUNCTION notify_channel() RETURNS trigger AS $$ BEGIN RAISE LOG 'Notify Triggered'; PERFORM pg_notify('testchannel', 'Testing'); RETURN NEW; END; $$ LANGUAGE 'plpgsql'; DROP TRIGGER queue_insert ON TEST; CREATE TRIGGER queue_insert AFTER INSERT ON test FOR EACH ROW EXECUTE PROCEDURE notify_channel(); ALTER TABLE test ENABLE ALWAYS TRIGGER queue_insert; LISTEN testchannel; Run the following insert on the master: INSERT INTO test (msg) VALUES ('test'); In postgresql-10-main.log I get the following: 2018-07-24 07:45:15.705 EDT [6701] LOG: 00000: Notify Triggered 2018-07-24 07:45:15.705 EDT [6701] CONTEXT: PL/pgSQL function notify_channel() line 3 at RAISE 2018-07-24 07:45:15.705 EDT [6701] LOCATION: exec_stmt_raise, pl_exec.c:3337 But no listeners receive the message. However if an insert is run directly on the replica: # INSERT INTO test VALUES (99999, 'test'); INSERT 0 1 Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 6701. Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 6701. Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 6701. Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 6701. Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 6701. Asynchronous notification "testchannel" with payload "Testing" received from server process with PID 9992. Backed up notifications are received for previous NOTIFY's. -
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Sergei Kornilov <sk@zsrv.org> — 2018-07-24T13:19:45Z
Hello Thank you for report I checked this bug and found reason: we do not notify backends about new events by call ProcessCompletedNotifies from logical worker. New notify from regular backend does call ProcessCompletedNotifies: send signal to all listen backends and found new events for youself. But i am not sure where is correct place for call ProcessCompletedNotifies in logical worker src/backend/replication/logical/worker.c and i can not provide patch. regards, Sergei
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Andres Freund <andres@anarazel.de> — 2018-07-24T15:58:29Z
Hi, On 2018-07-24 16:19:45 +0300, Sergei Kornilov wrote: > I checked this bug and found reason: we do not notify backends about new events by call ProcessCompletedNotifies from logical worker. > New notify from regular backend does call ProcessCompletedNotifies: send signal to all listen backends and found new events for youself. > But i am not sure where is correct place for call ProcessCompletedNotifies in logical worker src/backend/replication/logical/worker.c and i can not provide patch. Peter, Petr, this is the second report of this issue. Anything? Greetings, Andres Freund
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Marc Dean <marc.dean.jr@gmail.com> — 2018-07-24T17:43:30Z
If Sergei is correct, I would volunteer to work on the patch. I am completely new to the codebase but this issue affects me. According to the documentation for `ProcessCompletedNotifies()` it should be called just before going idle... so perhaps in src/backend/replication/logical/worker.c at the tail end of `apply_handle_commit`? Again.. just looking at the codebase today so if this is beyond beginner level I will assist w/ testing instead. On Tue, Jul 24, 2018 at 11:58 AM, Andres Freund <andres@anarazel.de> wrote: > Hi, > > On 2018-07-24 16:19:45 +0300, Sergei Kornilov wrote: > > I checked this bug and found reason: we do not notify backends about new > events by call ProcessCompletedNotifies from logical worker. > > New notify from regular backend does call ProcessCompletedNotifies: send > signal to all listen backends and found new events for youself. > > But i am not sure where is correct place for call > ProcessCompletedNotifies in logical worker src/backend/replication/logical/worker.c > and i can not provide patch. > > Peter, Petr, this is the second report of this issue. Anything? > > Greetings, > > Andres Freund > >
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Sergei Kornilov <sk@zsrv.org> — 2018-07-24T18:22:18Z
Hello in fact, I've already tried to build fix. Adding ProcessCompletedNotifies to apply_handle_commit fixed this issue and i think this is right place. In src/backend/tcop/postgres.c we call ProcessCompletedNotifies similar way after commit. This change pass make check-world. So i attach my two line patch. regards, Sergei
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Andres Freund <andres@anarazel.de> — 2018-07-24T19:27:40Z
Hi Tom, Peter, On 2018-07-24 21:22:18 +0300, Sergei Kornilov wrote: > in fact, I've already tried to build fix. Adding ProcessCompletedNotifies to apply_handle_commit fixed this issue and i think this is right place. In src/backend/tcop/postgres.c we call ProcessCompletedNotifies similar way after commit. This change pass make check-world. > So i attach my two line patch. > diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c > index 6ca6cdc..e54bd90 100644 > --- a/src/backend/replication/logical/worker.c > +++ b/src/backend/replication/logical/worker.c > @@ -37,6 +37,7 @@ > > #include "commands/tablecmds.h" > #include "commands/trigger.h" > +#include "commands/async.h" > > #include "executor/executor.h" > #include "executor/nodeModifyTable.h" > @@ -490,6 +491,7 @@ apply_handle_commit(StringInfo s) > replorigin_session_origin_timestamp = commit_data.committime; > > CommitTransactionCommand(); > + ProcessCompletedNotifies(); > pgstat_report_stat(false); > > store_flush_position(commit_data.end_lsn); That's probably reasonable for the back branches (although I'd put the store_flush_position before). But I wonder if we shouldn't actually move the signalling part of ProcessCompletedNotifies() into CommitTransactionCommand() in v11. Given that transactions can now commit without a ready command being sent, due to the addition of procedures, that kind of seems necessary? Greetings, Andres Freund
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2018-07-24T21:43:30Z
Andres Freund <andres@anarazel.de> writes: > But I wonder if we shouldn't actually move the signalling part of > ProcessCompletedNotifies() into CommitTransactionCommand() in v11. Given > that transactions can now commit without a ready command being sent, due > to the addition of procedures, that kind of seems necessary? Hrm. I have a nasty feeling that that code is dependent on being executed at the outermost logic level. In particular, ProcessCompletedNotifies calls CommitTransactionCommand itself, so your proposal will create infinite recursion. There may be some other issues too. Another question that needs consideration is whether an internal commit should lead to immediate distribution of notifies to our own client. I think it probably mustn't; from the standpoint of the client, its originally-asked-for xact is still in progress, and it's not going to expect any notifies until that ends. So the proposed change is just wrong if you ask me. I agree we need some serious rethinking here. Maybe the fix will end up being just a few lines, but it might take significant restructuring too. regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Andres Freund <andres@anarazel.de> — 2018-07-24T21:56:04Z
Hi, On 2018-07-24 17:43:30 -0400, Tom Lane wrote: > Andres Freund <andres@anarazel.de> writes: > > But I wonder if we shouldn't actually move the signalling part of > > ProcessCompletedNotifies() into CommitTransactionCommand() in v11. Given > > that transactions can now commit without a ready command being sent, due > > to the addition of procedures, that kind of seems necessary? > > Hrm. I have a nasty feeling that that code is dependent on being executed > at the outermost logic level. In particular, ProcessCompletedNotifies > calls CommitTransactionCommand itself, so your proposal will create > infinite recursion. There may be some other issues too. Yea, I don't think we could do this without separating concerns in ProcessCompletedNotifies(). > Another question that needs consideration is whether an internal commit > should lead to immediate distribution of notifies to our own client. > I think it probably mustn't; from the standpoint of the client, its > originally-asked-for xact is still in progress, and it's not going to > expect any notifies until that ends. Yea, I agree on that. > So the proposed change is just wrong if you ask me. I was only proposing to move the signalling part of ProcessCompletedNotifies() into CommitTransactionCommand(), not the part that processes notifications for the currentbackend - so I don't think we actually disagree? > I agree we need some serious rethinking here. Maybe the fix will end > up being just a few lines, but it might take significant restructuring > too. Yea :(. I think we need to separate the SignalBackend() part into transaction commit, but leave the remainder of ProcessCompletedNotifies() to be done in outer loops like PostgresMain(). I'm not quite sure if there's a good way to handle the fact that currently the asyncQueueAdvanceTail() call depends on SignalBackend()'s return value. We probably don't want to do that work inside the CommitTransactionCommand() - i guess we could move to just doing it independent of SignalBackend()? One other thing, somewhat independent, I wonder is if it's actually problematic that we don't do ProcessCompletedNotifies() in a bunch of processes, because that means we'll not necessarily call asyncQueueAdvanceTail(). Perhaps that means we actually *do* need to do it around CommitTransactionCommand()? Greetings, Andres Freund
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2018-07-24T22:01:33Z
Andres Freund <andres@anarazel.de> writes: > One other thing, somewhat independent, I wonder is if it's actually > problematic that we don't do ProcessCompletedNotifies() in a bunch of > processes, because that means we'll not necessarily call > asyncQueueAdvanceTail(). Perhaps that means we actually *do* need to do > it around CommitTransactionCommand()? As far as that goes, we should probably ensure that a process that hasn't executed any LISTENs is ignored for purposes of whether to advance the queue tail. I think it might be like that already. regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Andres Freund <andres@anarazel.de> — 2018-07-24T22:06:30Z
On 2018-07-24 18:01:33 -0400, Tom Lane wrote: > Andres Freund <andres@anarazel.de> writes: > > One other thing, somewhat independent, I wonder is if it's actually > > problematic that we don't do ProcessCompletedNotifies() in a bunch of > > processes, because that means we'll not necessarily call > > asyncQueueAdvanceTail(). Perhaps that means we actually *do* need to do > > it around CommitTransactionCommand()? > > As far as that goes, we should probably ensure that a process that hasn't > executed any LISTENs is ignored for purposes of whether to advance the > queue tail. I think it might be like that already. It indeed is: min = QUEUE_HEAD; for (i = 1; i <= MaxBackends; i++) { if (QUEUE_BACKEND_PID(i) != InvalidPid) min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); } what I am wondering is what happens if there's a background worker (like the replication worker, but it could be other things too) that queues notifications, but no normal backends are actually listening. As far as I can tell, in that case we'd continue to queue stuff into the slru, but wouldn't actually clean things up until a normal session gets around to it? Which might be a while, on e.g. a logical replica. Greetings, Andres Freund -
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Robert Welin <robert@vaion.com> — 2019-02-22T16:37:50Z
I have reproduced this bug on PostgreSQL version 10.7 and 11.2 using the steps described in Michael Powers' original report. The issue also still seems to be present even with the patch provided by Sergei Kornilov. Are there plans to address this issue any time soon or is there some way I can assist in fixing it? It would be great to have notifications from logical replication. Regards, Robert Welin
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Marc Dean <marc.dean.jr@gmail.com> — 2019-02-28T01:01:16Z
If you are trying to get around the issue for now, what my team did was cron an insert statement on the database server. We have a queue table that has some of these triggers setup so it was easy to write a no-op row to the queue. This had the side effect of flushing the notification queue. We haven't had any issues with this approach. I can also volunteer to help test out patches. Thanks, -mdj On Fri, Feb 22, 2019 at 11:37 AM Robert Welin <robert@vaion.com> wrote: > I have reproduced this bug on PostgreSQL version 10.7 and 11.2 using the > steps described in Michael Powers' original report. The issue also still > seems to be present even with the patch provided by Sergei Kornilov. > > Are there plans to address this issue any time soon or is there some way > I can assist in fixing it? It would be great to have notifications from > logical replication. > > Regards, > Robert Welin > >
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Alvaro Herrera <alvherre@2ndquadrant.com> — 2019-06-28T21:22:24Z
On 2019-Feb-22, Robert Welin wrote: > I have reproduced this bug on PostgreSQL version 10.7 and 11.2 using the > steps described in Michael Powers' original report. The issue also still > seems to be present even with the patch provided by Sergei Kornilov. > > Are there plans to address this issue any time soon or is there some way > I can assist in fixing it? It would be great to have notifications from > logical replication. This issue seems largely forgotten about :-( -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Alan Kleiman <alan.kleiman@ifood.com.br> — 2019-08-29T15:03:22Z
On Fri, Feb 22, 2019 at 11:37 AM Robert Welin <robert(at)vaion(dot)com> wrote: > I have reproduced this bug on PostgreSQL version 10.7 and 11.2 using the > steps described in Michael Powers' original report. The issue also still > seems to be present even with the patch provided by Sergei Kornilov. > > Are there plans to address this issue any time soon or is there some way > I can assist in fixing it? It would be great to have notifications from > logical replication. > > Same, I've reproduced this on 11.4 and 10.9. Are there any plans to address this? If there's nothing in the short-term, can we get a caveat in the documentation for notify/logical replication explaining this shortcoming? -- Alan Kleiman alan.kleiman@ifood.com.br
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Daniel Danzberger <daniel@dd-wrt.com> — 2020-06-23T09:40:53Z
On Fri, 2019-06-28 at 17:22 -0400, Alvaro Herrera wrote: > On 2019-Feb-22, Robert Welin wrote: > > > I have reproduced this bug on PostgreSQL version 10.7 and 11.2 > > using the > > steps described in Michael Powers' original report. The issue also > > still > > seems to be present even with the patch provided by Sergei > > Kornilov. > > > > Are there plans to address this issue any time soon or is there > > some way > > I can assist in fixing it? It would be great to have notifications > > from > > logical replication. > > This issue seems largely forgotten about :-( > Are there any news to this issue ? I can reproduce this bug up to now with version 12. -- Regards Daniel Danzberger embeDD GmbH, Alter Postplatz 2, CH-6370 Stans
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Sergey Fedchenko <seregayoga@bk.ru> — 2021-06-14T11:17:24Z
Hi all! I still can reproduce it on 14beta1 version. I adapted a patch I found in this thread https://github.com/seregayoga/postgres/commit/338bc33f2cf77edde7c45bfdfb9f39a92ec57eb8 . It solved this bug for me (tested with simple Go program using https://github.com/lib/pq ). It would be nice to have this bug fixed. I’m not so familiar with postgres code base, but would glad to help with testing. >Monday, June 14, 2021 12:39 PM +03:00 from Daniel Danzberger < daniel@dd-wrt.com >: > >On Fri, 2019-06-28 at 17:22 -0400, Alvaro Herrera wrote: >> On 2019-Feb-22, Robert Welin wrote: >> >> > I have reproduced this bug on PostgreSQL version 10.7 and 11.2 >> > using the >> > steps described in Michael Powers' original report. The issue also >> > still >> > seems to be present even with the patch provided by Sergei >> > Kornilov. >> > >> > Are there plans to address this issue any time soon or is there >> > some way >> > I can assist in fixing it? It would be great to have notifications >> > from >> > logical replication. >> >> This issue seems largely forgotten about :-( >> >Are there any news to this issue ? >I can reproduce this bug up to now with version 12. > >-- >Regards > >Daniel Danzberger >embeDD GmbH, Alter Postplatz 2, CH-6370 Stans > > > > Best regards, Sergey Fedchenko.
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Artur Zakirov <artur.zakirov@adjust.com> — 2021-07-22T09:04:07Z
Hello hackers, On Wed, Jul 14, 2021 at 11:30 AM Sergey Fedchenko <seregayoga@bk.ru> wrote: > > Hi all! I still can reproduce it on 14beta1 version. I adapted a patch I found in this thread https://github.com/seregayoga/postgres/commit/338bc33f2cf77edde7c45bfdfb9f39a92ec57eb8 . It solved this bug for me (tested with simple Go program using https://github.com/lib/pq). It would be nice to have this bug fixed. I’m not so familiar with postgres code base, but would glad to help with testing. In our company in one of our projects we ran into this bug too. I attached the patch which fixes it in a different way. It calls SignalBackends() in AtCommit_Notify(). It is possible to call SignalBackends() outside of ProcessCompletedNotifies() after the commit 51004c7172b5c35afac050f4d5849839a06e8d3b, which removes necessity of checking of SignalBackends()'s result. Moving SignalBackends() to AtCommit_Notify() makes it possible to signal backends by "non-normal" backends including logical replication workers. It seems it is safe to call SignalBackends() in AtCommit_Notify() since SignalBackends() doesn't raise any error except OOM. Regarding Andres concern: > what I am wondering is what happens if there's a background worker (like > the replication worker, but it could be other things too) that queues > notifications, but no normal backends are actually listening. As far as > I can tell, in that case we'd continue to queue stuff into the slru, but > wouldn't actually clean things up until a normal session gets around to > it? Which might be a while, on e.g. a logical replica. A backend which raises notifications calls asyncQueueAdvanceTail() sometimes, which truncates pages up to new tail, which is equal to head if there are no listening backends. But there will be a problem if there is a backend which is listening but it doesn't process incoming notifications and doesn't update its queue position. In that case asyncQueueAdvanceTail() is able to advance tail only up to that backend's queue position. -- Artur Zakirov PostgreSQL Developer at Adjust
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2021-09-06T19:27:32Z
Artur Zakirov <artur.zakirov@adjust.com> writes: > I attached the patch which fixes it in a different way. It calls > SignalBackends() in AtCommit_Notify(). It is possible to call SignalBackends() > outside of ProcessCompletedNotifies() after the commit > 51004c7172b5c35afac050f4d5849839a06e8d3b, which removes necessity of checking > of SignalBackends()'s result. Hm. So that forecloses back-patching this to earlier than v13. On the other hand, given that we've been ignoring the bug for awhile, maybe a fix that only works in v13+ is good enough. (Or maybe by now it'd be safe to back-patch the v13-era async.c changes? Don't really want to, though.) The larger problem with this patch is exactly what Andres said: if a replication worker or other background process is sending notifies, but no normal backend is listening, then nothing will ever call asyncQueueAdvanceTail() so the message queue will bloat until it overflows and things start failing. That's not OK. Perhaps it could be fixed by moving the "if (backendTryAdvanceTail)" stanza into AtCommit_Notify. That's not ideal, because really it's best to not do that till after we've read our own notifies, but it might be close enough. At that point ProcessCompletedNotifies's only responsibility would be to call asyncQueueReadAllNotifications, which would allow some simplifications. There are some sort-of-cosmetic-but-important-for-future-proofing issues too: * I think that it's safe to move these actions to AtCommit_Notify, given where that is called in the CommitTransaction sequence, but there is nothing in xact.c suggesting that that call is in any way ordering-critical (because today, it isn't). I think we need some comments there to prevent somebody from breaking this in future. Maybe about like smgrDoPendingDeletes(true); + /* + * Send out notification signals to other backends (and do other + * post-commit NOTIFY cleanup). This must not happen until after + * our transaction is fully done from the viewpoint of other + * backends. + */ AtCommit_Notify(); + /* + * Everything after this should be purely-internal-to-this-backend + * cleanup. + */ AtEOXact_GUC(true, 1); * You need to spend more effort on the comments in async.c too. Some of these changes are wrong plus there are places that should be changed and weren't. Also, postgres.c's comment about ProcessCompletedNotifies is invalidated by this patch. * There is some verbiage about NOTIFY in bgworker.sgml, which looks like it may be wrong now, and it certainly will be wrong after this patch. We don't want to be encouraging bgworkers to call ProcessCompletedNotifies. Maybe we should rename it, to force the issue? regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Artur Zakirov <artur.zakirov@adjust.com> — 2021-09-11T19:55:16Z
Thank you Tom for your review. On Mon, Sep 6, 2021 at 9:27 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: > > Artur Zakirov <artur.zakirov@adjust.com> writes: > > I attached the patch which fixes it in a different way. It calls > > SignalBackends() in AtCommit_Notify(). It is possible to call SignalBackends() > > outside of ProcessCompletedNotifies() after the commit > > 51004c7172b5c35afac050f4d5849839a06e8d3b, which removes necessity of checking > > of SignalBackends()'s result. > > Hm. So that forecloses back-patching this to earlier than v13. > On the other hand, given that we've been ignoring the bug for awhile, > maybe a fix that only works in v13+ is good enough. (Or maybe by now > it'd be safe to back-patch the v13-era async.c changes? Don't really > want to, though.) I think it would be better to back-patch the fix to older versions than v13. But considering that the new patch renames ProcessCompletedNotifies(), it can break existing applications which use background workers and NOTIFY. Users can be upset with the change, since they don't face the original bug, they just call ProcessCompletedNotifies() manually. In that case v13+ fix can be good enough. But users who use logical replication and have the NOTIFY bug will have to update to the new version of Postgres. > The larger problem with this patch is exactly what Andres said: if > a replication worker or other background process is sending notifies, > but no normal backend is listening, then nothing will ever call > asyncQueueAdvanceTail() so the message queue will bloat until it > overflows and things start failing. That's not OK. Perhaps it > could be fixed by moving the "if (backendTryAdvanceTail)" stanza > into AtCommit_Notify. That's not ideal, because really it's best > to not do that till after we've read our own notifies, but it might > be close enough. At that point ProcessCompletedNotifies's only > responsibility would be to call asyncQueueReadAllNotifications, > which would allow some simplifications. Agree, I moved asyncQueueAdvanceTail() to AtCommit_Notify(). > * I think that it's safe to move these actions to AtCommit_Notify, > given where that is called in the CommitTransaction sequence, but > there is nothing in xact.c suggesting that that call is in any way > ordering-critical (because today, it isn't). I think we need some > comments there to prevent somebody from breaking this in future. > Maybe about like I added comments before and after AtCommit_Notify(). > * You need to spend more effort on the comments in async.c too. Some > of these changes are wrong plus there are places that should be changed > and weren't. Also, postgres.c's comment about ProcessCompletedNotifies > is invalidated by this patch. I fixed these parts. I removed some excessive changes and also fixed the comment in postgres.c. > * There is some verbiage about NOTIFY in bgworker.sgml, which looks > like it may be wrong now, and it certainly will be wrong after this > patch. We don't want to be encouraging bgworkers to call > ProcessCompletedNotifies. Maybe we should rename it, to force > the issue? I removed this part of documentation and renamed the function to ProcessBackendNotifies(). It process only self-notifies now, but ProcessBackendNotifies is good enough to express that the function processes notifies of the backend. I also renamed backendTryAdvanceTail to tryAdvanceTail, since it is used not only by backends. -- Artur
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2021-09-11T22:16:09Z
Artur Zakirov <artur.zakirov@adjust.com> writes: > On Mon, Sep 6, 2021 at 9:27 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: >> Hm. So that forecloses back-patching this to earlier than v13. >> On the other hand, given that we've been ignoring the bug for awhile, >> maybe a fix that only works in v13+ is good enough. (Or maybe by now >> it'd be safe to back-patch the v13-era async.c changes? Don't really >> want to, though.) > I think it would be better to back-patch the fix to older versions > than v13. But considering that the new patch renames > ProcessCompletedNotifies(), it can break existing applications which > use background workers and NOTIFY. Users can be upset with the change, > since they don't face the original bug, they just call > ProcessCompletedNotifies() manually. I've not looked at your new patch yet, but I did spend a little time checking into whether it'd be sane to backpatch 51004c717, which changed SignalBackends' API. (We'd also need the non-catalog parts of 8b7ae5a82, presumably.) I came away feeling that the benefit isn't worth the effort and risk. There was an awful lot of churn in async.c since v12, and to make matters worse, some of it was back-patched already while some wasn't. So 51004c717 doesn't apply to v12 at all cleanly, and some of the merge problems are due to code that's older than that commit but others are due to code that's newer. It would take some work just to get a patch that applies, and I would not have a lot of faith in the result. I think we're better off just settling for a back-patch to v13. The delta in async.c between v13 and HEAD is not very large, so we'd not be taking too much risk in going that far back. As far as ProcessCompletedNotifies is concerned, I think what we could do in the back branches is leave it in place as an empty, no-op function, so as not to break extensions that are following the existing documentation by calling it. regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2021-09-12T17:29:58Z
Artur Zakirov <artur.zakirov@adjust.com> writes: > [ v2-0001-signal-backends-on-commit.patch ] I had an epiphany while looking at this. Now that PostgresMain calls ProcessNotifyInterrupt at the same place it calls ProcessCompletedNotifies (which it does since 790026972), we don't actually need ProcessCompletedNotifies to read self-notifies either. If we merely set notifyInterruptPending, ProcessNotifyInterrupt will handle that just fine. With the other changes already under discussion, this means ProcessCompletedNotifies can go away entirely. That's not only less code, but fewer cycles: in cases where we have both self-notifies and inbound notify signals, the existing code starts two transactions and runs asyncQueueReadAllNotifications twice, but there's no need to do it more than once. Self-notifies become less of a special case on the sending side too, since we can just treat that as signalling ourselves --- though it still seems worthwhile to optimize that by setting notifyInterruptPending directly instead of invoking kill(). Hence, I present the attached, which also tweaks things to avoid an extra pq_flush in the end-of-command code path, and improves the comments to discuss the issue of NOTIFYs sent by procedures. There is still a loose end we ought to think about: what to do when someone issues LISTEN in a background worker. With the code as it stands, or with this patch, the worker will block cleanout of the async SLRU since it will never read any messages. (With the code as it stands, a bgworker author can ameliorate that by calling ProcessCompletedNotifies, but this patch is going to either eliminate ProcessCompletedNotifies or turn it into a no-op. In any case, we still have a problem if an ill-considered trigger issues LISTEN in a replication worker.) I'm inclined to think we should flat-out reject LISTEN in any process that is not attached to a frontend, at least until somebody takes the trouble to add infrastructure that would let it be useful. I've not done that here though; I'm not quite sure what we should test for. regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Tom Lane <tgl@sss.pgh.pa.us> — 2021-09-14T21:56:58Z
I wrote: > Hence, I present the attached, which also tweaks things to avoid an > extra pq_flush in the end-of-command code path, and improves the > comments to discuss the issue of NOTIFYs sent by procedures. Hearing no comments, I pushed that. > I'm inclined to think we should flat-out reject LISTEN in any process > that is not attached to a frontend, at least until somebody takes the > trouble to add infrastructure that would let it be useful. I've not > done that here though; I'm not quite sure what we should test for. After a bit of looking around, it seems that MyBackendType addresses that problem nicely, so I propose the attached. regards, tom lane
-
Re: BUG #15293: Stored Procedure Triggered by Logical Replication is Unable to use Notification Events
Artur Zakirov <artur.zakirov@adjust.com> — 2021-09-15T12:03:25Z
On Wed, Sep 15, 2021 at 2:57 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > Hearing no comments, I pushed that. Thank you! > > I'm inclined to think we should flat-out reject LISTEN in any process > > that is not attached to a frontend, at least until somebody takes the > > trouble to add infrastructure that would let it be useful. I've not > > done that here though; I'm not quite sure what we should test for. > > After a bit of looking around, it seems that MyBackendType addresses > that problem nicely, so I propose the attached. Indeed, it seems only regular backends can send out notifies to frontends. In that case there is no point in supporting LISTEN to other processes. I guess a background worker can try it with SPI, but with no luck. +1 from my sight. -- Artur