Thread
Commits
-
Avoid assertion failure with LISTEN in a serializable transaction.
- bd743b600619 10.12 landed
- d9bb71947949 11.7 landed
- a24a4167aa38 12.2 landed
- 6b802cfc7fab 13.0 landed
- 864e8080e190 9.5.21 landed
- 34f44f59b38f 9.4.26 landed
- cdba85eb01ed 9.6.17 landed
-
Stabilize NOTIFY behavior by transmitting notifies before ReadyForQuery.
- dbe15524becb 10.12 landed
- c47f498c93f9 12.2 landed
- 790026972442 13.0 landed
- 377d1b95bfeb 11.7 landed
- 111298aa6533 9.6.17 landed
-
Stabilize the results of pg_notification_queue_usage().
- 8b7ae5a82d04 13.0 landed
-
LISTEN/NOTIFY testing woes
Tom Lane <tgl@sss.pgh.pa.us> — 2019-11-24T01:01:42Z
I ran into a couple of issues while trying to devise a regression test illustrating the LISTEN-in-serializable-transaction issue Mark Dilger reported. The first one is that an isolation test in which we expect to see a cross-process NOTIFY immediately after a COMMIT turns out to be not very stable: on my machine, it works as long as you're just running the isolation tests by themselves, but it usually falls over if I'm running check-world with any amount of parallelism. The reason for this seems to be that incoming notifies are only checked for when we're about to wait for client input. At that point we've already sent the ReadyForQuery ('Z') protocol message, which will cause libpq to stand down from looking for more input and return a null from PQgetResult(). Depending on timing, the following Notify protocol messages might arrive quickly enough that isolationtester.c sees them before it goes off to do something else, but that's not very reliable. In the case of self-notifies, postgres.c ensures that those get transmitted to the frontend *before* ReadyForQuery, and this is what makes self-notify cases stable enough to survive buildfarm testing. I'm a bit surprised, now that I've seen this effect, that the existing cross-session notify tests in async-notify.spec haven't given us problems in the buildfarm. (Maybe, now that I just pushed those into the back branches, we'll start to see some failures?) Anyway, what I propose to do about this is patch 0001 attached, which tweaks postgres.c to ensure that any cross-session notifies that arrived during the just-finished transaction are also guaranteed to be sent to the client before, not after, ReadyForQuery. Another thing that I discovered while testing this is that as of HEAD, you can't run "make installcheck" for the isolation tests more than once without restarting the server. If you do, you get a test result mismatch because the async-notify test's first invocation of pg_notification_queue_usage() returns a positive value. Which is entirely unsurprising, because the previous iteration ensured that it would, and we've done nothing to make the queue tail advance since then. This seems both undesirable for our own testing, and rather bogus from users' standpoints as well. However, I think a simple fix is available: just make the SQL pg_notification_queue_usage() function advance the queue tail before measuring, as in 0002 below. This will restore the behavior of that function to what it was before 51004c717, and it doesn't seem like it'd cost any performance in any plausible use-cases. 0002 is only needed in HEAD, but I'll have to back-patch 0001 as far as 9.6, to support a test case for the problem Mark discovered and to ensure that back-patching b10f40bf0 doesn't cause any issues. BTW, the fix and test case for Mark's issue look like 0003. Without the 0001 patch, it's unstable exactly when the "listener2: NOTIFY "c1" with payload "" from notifier" message comes out. But modulo that issue, this test case reliably shows the assertion failure in the back branches. regards, tom lane -
Re: LISTEN/NOTIFY testing woes
Mark Dilger <hornschnorter@gmail.com> — 2019-11-24T04:50:52Z
On 11/23/19 5:01 PM, Tom Lane wrote: > I ran into a couple of issues while trying to devise a regression test > illustrating the LISTEN-in-serializable-transaction issue Mark Dilger > reported. The first one is that an isolation test in which we expect > to see a cross-process NOTIFY immediately after a COMMIT turns out to > be not very stable: on my machine, it works as long as you're just > running the isolation tests by themselves, but it usually falls over > if I'm running check-world with any amount of parallelism. The reason > for this seems to be that incoming notifies are only checked for when > we're about to wait for client input. At that point we've already > sent the ReadyForQuery ('Z') protocol message, which will cause libpq > to stand down from looking for more input and return a null from > PQgetResult(). Depending on timing, the following Notify protocol > messages might arrive quickly enough that isolationtester.c sees them > before it goes off to do something else, but that's not very reliable. Thanks for working on this, Tom. I have finished reading and applying your three patches and have moved on to testing them. I hope to finish the review soon. -- Mark Dilger -
Re: LISTEN/NOTIFY testing woes
Martijn van Oosterhout <kleptog@gmail.com> — 2019-11-24T13:19:39Z
Hoi Tom, On Sun, 24 Nov 2019 at 02:01, Tom Lane <tgl@sss.pgh.pa.us> wrote: > > This seems both undesirable for our own testing, and rather bogus > from users' standpoints as well. However, I think a simple fix is > available: just make the SQL pg_notification_queue_usage() function > advance the queue tail before measuring, as in 0002 below. This will > restore the behavior of that function to what it was before 51004c717, > and it doesn't seem like it'd cost any performance in any plausible > use-cases. This was one of those open points in the previous patches where it wasn't quite clear what the correct behaviour should be. This fixes the issue, but the question in my mind is: do we want to document this fact and can users rely on this behaviour? If we go with the argument that the delay in cleaning up should be entirely invisible, then I guess this patch is the correct one that makes the made changes invisible. Arguably not doing this means we'd have to document the values are possibly out of date. So I think this patch does the right thing. Have a nice day, -- Martijn van Oosterhout <kleptog@gmail.com> http://svana.org/kleptog/
-
Re: LISTEN/NOTIFY testing woes
Tom Lane <tgl@sss.pgh.pa.us> — 2019-11-24T15:25:39Z
Martijn van Oosterhout <kleptog@gmail.com> writes: > On Sun, 24 Nov 2019 at 02:01, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> This seems both undesirable for our own testing, and rather bogus >> from users' standpoints as well. However, I think a simple fix is >> available: just make the SQL pg_notification_queue_usage() function >> advance the queue tail before measuring, as in 0002 below. This will >> restore the behavior of that function to what it was before 51004c717, >> and it doesn't seem like it'd cost any performance in any plausible >> use-cases. > This was one of those open points in the previous patches where it > wasn't quite clear what the correct behaviour should be. This fixes > the issue, but the question in my mind is: do we want to document this > fact and can users rely on this behaviour? If we go with the argument > that the delay in cleaning up should be entirely invisible, then I > guess this patch is the correct one that makes the made changes > invisible. Arguably not doing this means we'd have to document the > values are possibly out of date. > So I think this patch does the right thing. Thanks for looking! In the light of morning, there's one other thing bothering me about this patch: it means that the function has side-effects, even though those effects are at the implementation level and shouldn't be user-visible. We do already have it marked "volatile", so that's OK, but I notice that it's not parallel restricted. The isolation test still passes when I set force_parallel_mode = regress, so apparently it works to run this code in a parallel worker, but that seems pretty scary to me; certainly nothing in async.c was written with that in mind. I think we'd be well advised to adjust pg_proc.dat to mark pg_notification_queue_usage() as parallel-restricted, so that it only executes in the main session process. It's hard to see any use-case for parallelizing it that would justify even a small chance of new bugs. regards, tom lane
-
Re: LISTEN/NOTIFY testing woes
Mark Dilger <hornschnorter@gmail.com> — 2019-11-24T18:25:57Z
On 11/23/19 8:50 PM, Mark Dilger wrote: > > > On 11/23/19 5:01 PM, Tom Lane wrote: >> I ran into a couple of issues while trying to devise a regression test >> illustrating the LISTEN-in-serializable-transaction issue Mark Dilger >> reported. The first one is that an isolation test in which we expect >> to see a cross-process NOTIFY immediately after a COMMIT turns out to >> be not very stable: on my machine, it works as long as you're just >> running the isolation tests by themselves, but it usually falls over >> if I'm running check-world with any amount of parallelism. The reason >> for this seems to be that incoming notifies are only checked for when >> we're about to wait for client input. At that point we've already >> sent the ReadyForQuery ('Z') protocol message, which will cause libpq >> to stand down from looking for more input and return a null from >> PQgetResult(). Depending on timing, the following Notify protocol >> messages might arrive quickly enough that isolationtester.c sees them >> before it goes off to do something else, but that's not very reliable. > > Thanks for working on this, Tom. > > I have finished reading and applying your three patches and have moved > on to testing them. I hope to finish the review soon. After applying all three patches, the stress test that originally uncovered the assert in predicate.c no longer triggers any asserts. `check-world` passes. The code and comments look good. Your patches are ready for commit. -- Mark Dilger -
Re: LISTEN/NOTIFY testing woes
Tom Lane <tgl@sss.pgh.pa.us> — 2019-11-24T18:39:15Z
Mark Dilger <hornschnorter@gmail.com> writes: > On 11/23/19 8:50 PM, Mark Dilger wrote: >> I have finished reading and applying your three patches and have moved >> on to testing them. I hope to finish the review soon. > After applying all three patches, the stress test that originally > uncovered the assert in predicate.c no longer triggers any asserts. > `check-world` passes. The code and comments look good. Thanks for reviewing! After sleeping on it, I'm not really happy with what I did in PrepareTransaction (that is, invent a separate PrePrepare_Notify function). The idea was to keep that looking parallel to what CommitTransaction does, and preserve infrastructure against the day that somebody gets motivated to allow LISTEN or NOTIFY in a prepared transaction. But on second thought, what would surely happen when that feature gets added is just that AtPrepare_Notify would serialize the pending LISTEN/NOTIFY actions into the 2PC state file. There wouldn't be any need for PrePrepare_Notify, so there's no point in introducing that. I'll just move the comment saying that nothing has to happen at that point for NOTIFY. regards, tom lane
-
Re: LISTEN/NOTIFY testing woes
Mark Dilger <hornschnorter@gmail.com> — 2019-11-24T19:01:04Z
On 11/24/19 10:39 AM, Tom Lane wrote: > Mark Dilger <hornschnorter@gmail.com> writes: >> On 11/23/19 8:50 PM, Mark Dilger wrote: >>> I have finished reading and applying your three patches and have moved >>> on to testing them. I hope to finish the review soon. > >> After applying all three patches, the stress test that originally >> uncovered the assert in predicate.c no longer triggers any asserts. >> `check-world` passes. The code and comments look good. > > Thanks for reviewing! > > After sleeping on it, I'm not really happy with what I did in > PrepareTransaction (that is, invent a separate PrePrepare_Notify > function). The idea was to keep that looking parallel to what > CommitTransaction does, and preserve infrastructure against the > day that somebody gets motivated to allow LISTEN or NOTIFY in > a prepared transaction. But on second thought, what would surely > happen when that feature gets added is just that AtPrepare_Notify > would serialize the pending LISTEN/NOTIFY actions into the 2PC > state file. There wouldn't be any need for PrePrepare_Notify, > so there's no point in introducing that. I'll just move the > comment saying that nothing has to happen at that point for NOTIFY. I looked at that. I thought it was an interesting decision to factor out that error to its own function while leaving a similar error inline just a little below in xact.c: if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot PREPARE a transaction that has operated on temporary objects"))); I assumed you had factored it out in anticipation of supporting notify here in the future. If you want to backtrack that decision and leave it inline, you would still keep the test rather than just a comment, right? It sounds like you intend to let AtPrepare_Notify catch the problem later, but since that's just an Assert and not an ereport(ERROR), that provides less error checking for non-assert builds. -- Mark Dilger -
Re: LISTEN/NOTIFY testing woes
Tom Lane <tgl@sss.pgh.pa.us> — 2019-11-24T19:04:38Z
Mark Dilger <hornschnorter@gmail.com> writes: > On 11/24/19 10:39 AM, Tom Lane wrote: >> After sleeping on it, I'm not really happy with what I did in >> PrepareTransaction (that is, invent a separate PrePrepare_Notify >> function). The idea was to keep that looking parallel to what >> CommitTransaction does, and preserve infrastructure against the >> day that somebody gets motivated to allow LISTEN or NOTIFY in >> a prepared transaction. But on second thought, what would surely >> happen when that feature gets added is just that AtPrepare_Notify >> would serialize the pending LISTEN/NOTIFY actions into the 2PC >> state file. There wouldn't be any need for PrePrepare_Notify, >> so there's no point in introducing that. I'll just move the >> comment saying that nothing has to happen at that point for NOTIFY. > I assumed you had factored it out in anticipation of supporting notify > here in the future. If you want to backtrack that decision and leave it > inline, you would still keep the test rather than just a comment, right? No, there wouldn't be any error condition; that's just needed because the feature isn't implemented yet. So I'll leave that alone; the only thing that needs to happen now in the PREPARE code path is to adjust the one comment. regards, tom lane
-
Re: LISTEN/NOTIFY testing woes
Mark Dilger <hornschnorter@gmail.com> — 2019-11-24T19:24:35Z
On 11/24/19 11:04 AM, Tom Lane wrote: > Mark Dilger <hornschnorter@gmail.com> writes: >> On 11/24/19 10:39 AM, Tom Lane wrote: >>> After sleeping on it, I'm not really happy with what I did in >>> PrepareTransaction (that is, invent a separate PrePrepare_Notify >>> function). The idea was to keep that looking parallel to what >>> CommitTransaction does, and preserve infrastructure against the >>> day that somebody gets motivated to allow LISTEN or NOTIFY in >>> a prepared transaction. But on second thought, what would surely >>> happen when that feature gets added is just that AtPrepare_Notify >>> would serialize the pending LISTEN/NOTIFY actions into the 2PC >>> state file. There wouldn't be any need for PrePrepare_Notify, >>> so there's no point in introducing that. I'll just move the >>> comment saying that nothing has to happen at that point for NOTIFY. > >> I assumed you had factored it out in anticipation of supporting notify >> here in the future. If you want to backtrack that decision and leave it >> inline, you would still keep the test rather than just a comment, right? > > No, there wouldn't be any error condition; that's just needed because the > feature isn't implemented yet. So I'll leave that alone; the only thing > that needs to happen now in the PREPARE code path is to adjust the one > comment. Ok. -- Mark Dilger