Hello Jeff,

Ok, the problem was a little bit more trivial than I thought.

The issue is that under a low rate there may be no transaction in progress, however the wait procedure was relying on select's timeout. If nothing is active there is nothing to wait for, thus it was an active loop in this case...

I've introduced a usleep call in place of select for this particular case. Hopefully this is portable.

ISTM that this bug exists since rate was introduced, so shame on me and back-patching should be needed.

--
Fabien.
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index e37496c..068dbe6 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -4582,20 +4582,30 @@ threadRun(void *arg)
 		 * or it's time to print a progress report.  Update input_mask to show
 		 * which client(s) received data.
 		 */
-		if (min_usec > 0 && maxsock != -1)
+		if (min_usec > 0)
 		{
-			int			nsocks; /* return from select(2) */
+			int			nsocks = 0; /* return from select(2) if called, or usleep() */
 
 			if (min_usec != PG_INT64_MAX)
 			{
-				struct timeval timeout;
+				if (maxsock != -1)
+				{
+					struct timeval timeout;
 
-				timeout.tv_sec = min_usec / 1000000;
-				timeout.tv_usec = min_usec % 1000000;
-				nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout);
+					timeout.tv_sec = min_usec / 1000000;
+					timeout.tv_usec = min_usec % 1000000;
+					nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout);
+				}
+				else /* nothing active, simple sleep */
+				{
+					nsocks = usleep(min_usec);
+				}
 			}
-			else
+			else /* no delay, select without timeout */
+			{
 				nsocks = select(maxsock + 1, &input_mask, NULL, NULL, NULL);
+			}
+
 			if (nsocks < 0)
 			{
 				if (errno == EINTR)
@@ -4604,11 +4614,11 @@ threadRun(void *arg)
 					continue;
 				}
 				/* must be something wrong */
-				fprintf(stderr, "select() failed: %s\n", strerror(errno));
+				fprintf(stderr, "select() or usleep() failed: %s\n", strerror(errno));
 				goto done;
 			}
 		}
-		else
+		else /* min_usec == 0 */
 		{
 			/* If we didn't call select(), don't try to read any data */
 			FD_ZERO(&input_mask);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to