Fix pgpool crash when pgpool child process exits.
authorTatsuo Ishii <ishii@postgresql.org>
Wed, 18 Sep 2024 02:25:10 +0000 (11:25 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Wed, 18 Sep 2024 02:33:38 +0000 (11:33 +0900)
When a pgpool child process exits, close_all_backend_connections() is
called, which is responsible for closing all connections to backend in
the connection pool. It used mistakenly MAIN_CONNECTION macro, which
is fine for current active connections but is not good for pooled
connections because a main node could be different at the time when
the connection pool was created. Fix is using in_use_backend()
instead.

Reported-by: Emond Papegaaij
Backpatch-through: v4.2

src/protocol/pool_connection_pool.c

index 79ee7e786423a35d3a9b8988fde99fb33d936948..d7e1857a42350065b98ff567a349003ec7102c3d 100644 (file)
@@ -1073,11 +1073,15 @@ close_all_backend_connections(void)
 
        for (i = 0; i < pool_config->max_pool; i++, p++)
        {
-               if (!MAIN_CONNECTION(p))
+               int     backend_id = in_use_backend_id(p);
+
+               if (backend_id < 0)
                        continue;
-               if (!MAIN_CONNECTION(p)->sp)
+               if (CONNECTION_SLOT(p, backend_id) == NULL)
                        continue;
-               if (MAIN_CONNECTION(p)->sp->user == NULL)
+               if (CONNECTION_SLOT(p, backend_id)->sp == NULL)
+                       continue;
+               if (CONNECTION_SLOT(p, backend_id)->sp->user == NULL)
                        continue;
                pool_send_frontend_exits(p);
        }