Fix Pgpool-II hanging when error occurs in streaming replication mode and extended...
authorTatsuo Ishii <ishii@postgresql.org>
Fri, 1 Sep 2017 23:53:19 +0000 (08:53 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Sat, 2 Sep 2017 00:00:08 +0000 (09:00 +0900)
If backend returns ERROR, Pgpool-II reads message from frontend until
a sync message is sent. Previous code assumed next message is sync.
However it is possible that more message coming before the sync
message, it's a low probability though. Fix it to continue reading
messages until the sync message is read.

src/protocol/pool_proto_modules.c

index 1af53c3bac46c4dedced54f9fe520ff9c26b0d5c..6ab0c9dc1adb93003cfa792def7f4b8624f85b29 100644 (file)
@@ -3531,9 +3531,30 @@ static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *fronte
        pmsg = pool_pending_message_get(POOL_SYNC);
        if (pmsg == NULL)
        {
-               ProcessFrontendResponse(frontend, backend);
+               char kind;
+               int len;
+               POOL_PENDING_MESSAGE *msg;
+               char *contents;
+
+               for(;;)
+               {
+                       pool_read(frontend, &kind, sizeof(kind));
+                       pool_read(frontend, &len, sizeof(len));
+                       len = ntohl(len) - sizeof(len);
+                       if (len > 0)
+                               contents = pool_read2(frontend, len);
+                       if (kind == 'S')
+                       {
+                               msg = pool_pending_message_create('S', 0, NULL);
+                               pool_pending_message_add(msg);
+                               pool_pending_message_free_pending_message(msg);
+                               SimpleForwardToBackend(kind, frontend, backend, len, contents);
+                               break;
+                       }
+               }
        }
-       pool_pending_message_free_pending_message(pmsg);
+       else
+               pool_pending_message_free_pending_message(pmsg);
 
        /* Remove all pending messages except sync message */
        do