#endif
#ifdef XCP
-static void pgxc_node_init(PGXCNodeHandle *handle, int sock, bool global_session);
+static void pgxc_node_init(PGXCNodeHandle *handle, int sock,
+ bool global_session, int pid);
#else
static void pgxc_node_init(PGXCNodeHandle *handle, int sock);
#endif
* Structure stores state info and I/O buffers
*/
static void
-pgxc_node_init(PGXCNodeHandle *handle, int sock, bool global_session)
+pgxc_node_init(PGXCNodeHandle *handle, int sock, bool global_session, int pid)
{
char *init_str;
handle->sock = sock;
+ handle->backend_pid = pid;
handle->transaction_status = 'I';
handle->state = DN_CONNECTION_STATE_IDLE;
handle->read_only = true;
{
/* The node is requested */
List *allocate = list_make1_int(node);
- int *fds = PoolManagerGetConnections(allocate, NIL);
+ int *pids;
+ int *fds = PoolManagerGetConnections(allocate, NIL,
+ &pids);
if (!fds)
{
+ Assert(pids != NULL);
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("Failed to get pooled connections"),
"max_connections and max_pool_size configuration "
"parameters")));
}
- pgxc_node_init(&dn_handles[node], fds[0], true);
+ pgxc_node_init(&dn_handles[node], fds[0], true, pids[0]);
datanode_count++;
/*
if (dn_allocate || co_allocate)
{
int j = 0;
- int *fds = PoolManagerGetConnections(dn_allocate, co_allocate);
+ int *pids;
+ int *fds = PoolManagerGetConnections(dn_allocate, co_allocate, &pids);
if (!fds)
{
foreach(node_list_item, dn_allocate)
{
int node = lfirst_int(node_list_item);
- int fdsock = fds[j++];
+ int fdsock = fds[j];
+ int be_pid = pids[j++];
if (node < 0 || node >= NumDataNodes)
{
}
node_handle = &dn_handles[node];
- pgxc_node_init(node_handle, fdsock, is_global_session);
+ pgxc_node_init(node_handle, fdsock, is_global_session, be_pid);
dn_handles[node] = *node_handle;
datanode_count++;
}
foreach(node_list_item, co_allocate)
{
int node = lfirst_int(node_list_item);
+ int be_pid = pids[j];
int fdsock = fds[j++];
if (node < 0 || node >= NumCoords)
}
node_handle = &co_handles[node];
- pgxc_node_init(node_handle, fdsock, is_global_session);
+ pgxc_node_init(node_handle, fdsock, is_global_session, be_pid);
co_handles[node] = *node_handle;
coord_count++;
}
{
int n;
memcpy(&n, buf + 5 + i * sizeof(int), sizeof(int));
- *pids[i] = ntohl(n);
+ (*pids)[i] = ntohl(n);
}
return n32;
static void reload_database_pools(PoolAgent *agent);
static DatabasePool *find_database_pool(const char *database, const char *user_name, const char *pgoptions);
static DatabasePool *remove_database_pool(const char *database, const char *user_name);
-static int *agent_acquire_connections(PoolAgent *agent, List *datanodelist, List *coordlist);
+static int *agent_acquire_connections(PoolAgent *agent, List *datanodelist,
+ List *coordlist, int **connectionpids);
static int cancel_query_on_connections(PoolAgent *agent, List *datanodelist, List *coordlist);
static PGXCNodePoolSlot *acquire_connection(DatabasePool *dbPool, Oid node);
static void agent_release_connections(PoolAgent *agent, bool force_destroy);
* Get pooled connections
*/
int *
-PoolManagerGetConnections(List *datanodelist, List *coordlist)
+PoolManagerGetConnections(List *datanodelist, List *coordlist, int **pids)
{
int i;
ListCell *nodelist_item;
return NULL;
}
+ if (pool_recvpids(&poolHandle->port, pids) != totlen)
+ {
+ pfree(*pids);
+ *pids = NULL;
+ return NULL;
+ }
+
return fds;
}
* In case of error agent_acquire_connections will log
* the error and return NULL
*/
- fds = agent_acquire_connections(agent, datanodelist, coordlist);
+ fds = agent_acquire_connections(agent, datanodelist, coordlist,
+ &pids);
list_free(datanodelist);
list_free(coordlist);
pool_sendfds(&agent->port, fds, fds ? datanodecount + coordcount : 0);
if (fds)
pfree(fds);
+
+ /*
+ * Also send the PIDs of the remote backend processes serving
+ * these connections
+ */
+ pool_sendpids(&agent->port, pids, pids ? datanodecount + coordcount : 0);
+ if (pids)
+ pfree(pids);
break;
case 'h': /* Cancel SQL Command in progress on specified connections */
* acquire connection
*/
static int *
-agent_acquire_connections(PoolAgent *agent, List *datanodelist, List *coordlist)
+agent_acquire_connections(PoolAgent *agent, List *datanodelist,
+ List *coordlist, int **pids)
{
int i;
int *result;
errmsg("out of memory")));
}
+ *pids = (int *) palloc((list_length(datanodelist) + list_length(coordlist)) * sizeof(int));
+ if (*pids == NULL)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ }
+
/*
* There are possible memory allocations in the core pooler, we want
* these allocations in the contect of the database pool
*/
}
- result[i++] = PQsocket((PGconn *) agent->dn_connections[node]->conn);
+ result[i] = PQsocket((PGconn *) agent->dn_connections[node]->conn);
+ (*pids)[i++] = ((PGconn *) agent->dn_connections[node]->conn)->be_pid;
}
/* Save then in the array fds for Coordinators */
*/
}
- result[i++] = PQsocket((PGconn *) agent->coord_connections[node]->conn);
+ result[i] = PQsocket((PGconn *) agent->coord_connections[node]->conn);
+ (*pids)[i++] = ((PGconn *) agent->coord_connections[node]->conn)->be_pid;
}
MemoryContextSwitchTo(oldcontext);
/* fd of the connection */
int sock;
+ /* pid of the remote backend process */
+ int backend_pid;
+
/* Connection state */
char transaction_status;
DNConnectionState state;
extern void PoolManagerReconnect(void);
/* Get pooled connections */
-extern int *PoolManagerGetConnections(List *datanodelist, List *coordlist);
+extern int *PoolManagerGetConnections(List *datanodelist, List *coordlist,
+ int **pids);
/* Clean pool connections */
extern void PoolManagerCleanConnection(List *datanodelist, List *coordlist, char *dbname, char *username);