From 97fb88ea4a646343d5f0a8cd65b7e5f598785cb4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 9 Sep 2019 22:53:51 -0400 Subject: [PATCH] Fix isolationtester race condition for notices sent before blocking. If a test sends a notice just before blocking, it's possible on slow machines for isolationtester to detect the blocked state before it's consumed the notice. (For this to happen, the notice would have to arrive after isolationtester has waited for data for 10ms, so on fast/lightly-loaded machines it's hard to reproduce the failure.) But, if we have seen the backend as blocked, it's certainly already sent any notices it's going to send. Therefore, one more round of PQconsumeInput and PQisBusy should be enough to collect and process any such notices. Back-patch of 30717637c into v12. We're still discussing whether to back-patch this further and/or back-patch some other recent isolationtester fixes, but this much is provably necessary to make the test cases added by 27cc7cd2b stable in v12. Discussion: https://postgr.es/m/14616.1564251339@sss.pgh.pa.us Discussion: https://postgr.es/m/E1i7IqC-0000Uc-5H@gemulon.postgresql.org --- src/test/isolation/isolationtester.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c index 2f039b83ee..768b0bd3c1 100644 --- a/src/test/isolation/isolationtester.c +++ b/src/test/isolation/isolationtester.c @@ -764,6 +764,28 @@ try_complete_step(Step *step, int flags) if (waiting) /* waiting to acquire a lock */ { + /* + * Since it takes time to perform the lock-check query, + * some data --- notably, NOTICE messages --- might have + * arrived since we looked. We must call PQconsumeInput + * and then PQisBusy to collect and process any such + * messages. In the (unlikely) case that PQisBusy then + * returns false, we might as well go examine the + * available result. + */ + if (!PQconsumeInput(conn)) + { + fprintf(stderr, "PQconsumeInput failed: %s\n", + PQerrorMessage(conn)); + exit(1); + } + if (!PQisBusy(conn)) + break; + + /* + * conn is still busy, so conclude that the step really is + * waiting. + */ if (!(flags & STEP_RETRY)) printf("step %s: %s \n", step->name, step->sql); -- 2.50.0