Fix health check time out.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Mon, 21 Oct 2019 04:44:37 +0000 (13:44 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Mon, 21 Oct 2019 04:44:37 +0000 (13:44 +0900)
Heal check time out could happen in several places:

1) connect system call
2) select system call
3) read system call

1) was ok but in 2) and 3) it was possible that it could go into
infinite loop in Pgpool-II 3.7 or later. This was due to a mistake
when health check process was modified to be separate process in 3.7,
and back patched to 3.7 and above.

Discussion:
https://www.pgpool.net/pipermail/pgpool-hackers/2019-October/003458.html
https://www.pgpool.net/pipermail/pgpool-hackers/2019-October/003459.html

src/protocol/pool_process_query.c
src/utils/pool_stream.c

index b30ce1ccf38d33285fe966f2aa57122b1fcd6153..def37ae30144c195c66c01dba27d6b7130d3b8ff 100644 (file)
@@ -3,7 +3,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2018     PgPool Global Development Group
+ * Copyright (c) 2003-2019     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -698,7 +698,7 @@ pool_check_fd(POOL_CONNECTION * cp)
                save_errno = errno;
                if (fds == -1)
                {
-                       if (processType == PT_MAIN && processState == PERFORMING_HEALTH_CHECK && errno == EINTR && health_check_timer_expired)
+                       if (processType == PT_HEALTH_CHECK && errno == EINTR && health_check_timer_expired)
                        {
                                ereport(WARNING,
                                                (errmsg("health check timed out while waiting for reading data")));
index cfec0338ab77a33cb6edad13b1737ec5a98a6115..cd0c8ad2b5525c8c1fb700e0aef577d906364528 100644 (file)
@@ -200,6 +200,13 @@ pool_read(POOL_CONNECTION * cp, void *buf, int len)
 
                if (readlen == -1)
                {
+                       if (processType == PT_HEALTH_CHECK && health_check_timer_expired && errno == EINTR)
+                       {
+                               ereport(ERROR,
+                                               (errmsg("health check timed out while waiting for reading data")));
+                               return -1;
+                       }
+
                        if (errno == EINTR || errno == EAGAIN)
                        {
                                ereport(DEBUG5,