* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2020 PgPool Global Development Group
+ * Copyright (c) 2003-2024 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
extern int pool_pool_index(void);
extern void close_all_backend_connections(void);
extern void update_pooled_connection_count(void);
+extern int in_use_backend_id(POOL_CONNECTION_POOL *pool);
+
#endif /* pool_connection_pool_h */
POOL_CONNECTION_POOL *p = pool_connection_pool;
ConnectionInfo *info;
int save_errno = errno;
+ int main_node_id;
/*
* DROP DATABASE is ongoing.
if (ignore_sigusr1)
return;
-#ifdef NOT_USED
- ereport(DEBUG1,
- (errmsg("close connection request received")));
-#endif
-
for (j = 0; j < pool_config->max_pool; j++, p++)
{
- if (!MAIN_CONNECTION(p))
+ main_node_id = in_use_backend_id(p);
+ if (main_node_id < 0)
+ continue;
+
+ if (!CONNECTION_SLOT(p, main_node_id))
continue;
- if (!MAIN_CONNECTION(p)->sp)
+ if (!CONNECTION_SLOT(p, main_node_id)->sp)
continue;
- if (MAIN_CONNECTION(p)->sp->user == NULL)
+ if (CONNECTION_SLOT(p, main_node_id)->sp->user == NULL)
continue;
- if (MAIN_CONNECTION(p)->closetime > 0) /* idle connection? */
+ if (CONNECTION_SLOT(p, main_node_id)->closetime > 0) /* idle connection? */
{
-#ifdef NOT_USED
- ereport(DEBUG1,
- (errmsg("closing idle connection"),
- errdetail("user: %s database: %s", MAIN_CONNECTION(p)->sp->user, MAIN_CONNECTION(p)->sp->database)));
-#endif
+ bool freed = false;
pool_send_frontend_exits(p);
for (i = 0; i < NUM_BACKENDS; i++)
{
- if (!VALID_BACKEND(i))
+ if (!CONNECTION_SLOT(p, i))
continue;
- if (i == 0)
+ if (!freed)
{
- /*
- * only first backend allocated the memory for the start
- * up packet
- */
pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp);
CONNECTION_SLOT(p, i)->sp = NULL;
-
+ freed = true;
}
pool_close(CONNECTION(p, i));
}
static int check_socket_status(int fd);
static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int port, bool retry);
+#define TMINTMAX 0x7fffffff
+
/*
* initialize connection pools. this should be called once at the startup.
*/
POOL_CONNECTION_POOL *oldestp;
POOL_CONNECTION_POOL *ret;
ConnectionInfo *info;
+ int main_node_id;
POOL_CONNECTION_POOL *p = pool_connection_pool;
for (i = 0; i < pool_config->max_pool; i++)
{
- if (MAIN_CONNECTION(p) == NULL)
+ if (in_use_backend_id(p) < 0) /* is this connection pool out of use? */
{
ret = new_connection(p);
if (ret)
* discard it.
*/
oldestp = p = pool_connection_pool;
- closetime = MAIN_CONNECTION(p)->closetime;
+ closetime = TMINTMAX;
pool_index = 0;
for (i = 0; i < pool_config->max_pool; i++)
{
+ main_node_id = in_use_backend_id(p);
+ if (main_node_id < 0)
+ elog(ERROR, "no in use backend found"); /* this should not happen */
+
ereport(DEBUG1,
(errmsg("creating connection pool"),
errdetail("user: %s database: %s closetime: %ld",
- MAIN_CONNECTION(p)->sp->user,
- MAIN_CONNECTION(p)->sp->database,
- MAIN_CONNECTION(p)->closetime)));
+ CONNECTION_SLOT(p, main_node_id)->sp->user,
+ CONNECTION_SLOT(p, main_node_id)->sp->database,
+ CONNECTION_SLOT(p, main_node_id)->closetime)));
- if (MAIN_CONNECTION(p)->closetime < closetime)
+ if (CONNECTION_SLOT(p, main_node_id)->closetime < closetime)
{
- closetime = MAIN_CONNECTION(p)->closetime;
+ closetime = CONNECTION_SLOT(p, main_node_id)->closetime;
oldestp = p;
pool_index = i;
}
}
p = oldestp;
+ main_node_id = in_use_backend_id(p);
+ if (main_node_id < 0)
+ elog(ERROR, "no in use backend found"); /* this should not happen */
pool_send_frontend_exits(p);
ereport(DEBUG1,
(errmsg("creating connection pool"),
errdetail("discarding old %zd th connection. user: %s database: %s",
oldestp - pool_connection_pool,
- MAIN_CONNECTION(p)->sp->user,
- MAIN_CONNECTION(p)->sp->database)));
+ CONNECTION_SLOT(p, main_node_id)->sp->user,
+ CONNECTION_SLOT(p, main_node_id)->sp->database)));
for (i = 0; i < NUM_BACKENDS; i++)
{
- if (!VALID_BACKEND(i))
+ if (CONNECTION_SLOT(p, i) == NULL)
continue;
if (!freed)
void
pool_backend_timer(void)
{
-#define TMINTMAX 0x7fffffff
-
POOL_CONNECTION_POOL *p = pool_connection_pool;
int i,
j;
}
pool_get_my_process_info()->pooled_connections = count;
}
+
+/*
+ * Return the first node id in use.
+ * If no node is in use, return -1.
+ */
+int
+in_use_backend_id(POOL_CONNECTION_POOL *pool)
+{
+ int i;
+
+ for (i = 0; i < NUM_BACKENDS; i++)
+ {
+ if (pool->slots[i])
+ return i;
+ }
+
+ return -1;
+}