aboutsummaryrefslogtreecommitdiff
path: root/src/test/isolation/isolationtester.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-07-27 20:21:54 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-07-27 20:21:54 -0400
commit30717637c1c58fcd02980a6752c7e13c9de12b69 (patch)
tree77a80d7e82ac45a51428c9d5d6b7a749d34d0821 /src/test/isolation/isolationtester.c
parentebd49928215e3854d91167e798949a75b34958d0 (diff)
downloadpostgresql-30717637c1c58fcd02980a6752c7e13c9de12b69.tar.gz
postgresql-30717637c1c58fcd02980a6752c7e13c9de12b69.zip
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. This appears to explain the instability noted in commit ebd499282, so undo the hack therein to not print notices from insert-conflict-specconflict. Patch by me, diagnosis by Andres Freund. Discussion: https://postgr.es/m/14616.1564251339@sss.pgh.pa.us
Diffstat (limited to 'src/test/isolation/isolationtester.c')
-rw-r--r--src/test/isolation/isolationtester.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 6ab19b1e597..3ed055106b4 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -752,6 +752,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 <waiting ...>\n",
step->name, step->sql);