Le 03/08/2010 13:29, Guillaume Lelarge a écrit :
> Le 03/08/2010 12:23, Tatsuo Ishii a écrit :
>>> Le 03/08/2010 03:48, Tatsuo Ishii a écrit :
>>>>>>> AFAICT, it works really good. We still miss pgsql_pid. And should I add
>>>>>>> some other reports? what do other people need?
>>>>>>>
>>>>>>
>>>>>> No comments on this patch? meaning I should commit it or not?
>>>>>
>>>>> I was waiting for you add pgsql_pid. Have you done it?
>>>>
>>>> I have added new function:
>>>> /*
>>>> * Return pointer to i th child, j th connection pool and k th backend
>>>> * of connection info on shmem.
>>>> */
>>>> ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend)
>>>>
>>>> I hope this will make your implementation regarding pgsql_pid easier.
>>>> For example, pool_coninfo(10, 0, 1) will return pointer to
>>>> ConnectionInfo corresponds to 1th backend pid which is in 0th
>>>> connection pool in 10th pgpool child.
>>>
>>> Sorry for not answering sooner. I thought you were working on adding
>>> pgsql_pid. There was a little misunderstanding :)
>>
>> Oh, I thought I woould work on pcp command, you would work on show
>> command.
>>
>
> No problem :)
>
> I'll work on it ASAP.
>
With your last commits, it makes it quite easy to do. Here is my new
patch. I still have an issue and perhaps you have an idea on how to
resolve it. Is there a way to know which connection is the active one in
a pool?
--
Guillaume
http://www.postgresql.fr
http://dalibo.com
Index: pool_process_query.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_process_query.c,v
retrieving revision 1.233
diff -c -p -r1.233 pool_process_query.c
*** pool_process_query.c 3 Aug 2010 06:37:18 -0000 1.233
--- pool_process_query.c 5 Aug 2010 12:06:37 -0000
*************** POOL_STATUS pool_parallel_exec(POOL_CONN
*** 461,467 ****
fd_set writemask;
fd_set exceptmask;
unsigned long donemask[FD_SETSIZE / BITS];
! static char *sq = "show pool_status";
POOL_STATUS status;
struct timeval timeout;
int num_fds;
--- 461,471 ----
fd_set writemask;
fd_set exceptmask;
unsigned long donemask[FD_SETSIZE / BITS];
! static char *sq_config = "show pool_status";
! static char *sq_pools = "show pool_pools";
! static char *sq_processes = "show pool_processes";
! static char *sq_nodes = "show pool_nodes";
! static char *sq_version = "show pool_version";
POOL_STATUS status;
struct timeval timeout;
int num_fds;
*************** POOL_STATUS pool_parallel_exec(POOL_CONN
*** 488,501 ****
}
/* process status reporting? */
! if (strncasecmp(sq, string, strlen(sq)) == 0)
{
pool_debug("process reporting");
! process_reporting(frontend, backend);
pool_unset_query_in_progress();
return POOL_CONTINUE;
}
/* In this loop,forward the query to the all backends */
for (i=0;i<NUM_BACKENDS;i++)
{
--- 492,537 ----
}
/* process status reporting? */
! if (strncasecmp(sq_config, string, strlen(sq_config)) == 0)
! {
! pool_debug("config reporting");
! config_reporting(frontend, backend);
! pool_unset_query_in_progress();
! return POOL_CONTINUE;
! }
!
! if (strncasecmp(sq_pools, string, strlen(sq_pools)) == 0)
! {
! pool_debug("pools reporting");
! pools_reporting(frontend, backend);
! pool_unset_query_in_progress();
! return POOL_CONTINUE;
! }
!
! if (strncasecmp(sq_processes, string, strlen(sq_processes)) == 0)
{
pool_debug("process reporting");
! processes_reporting(frontend, backend);
pool_unset_query_in_progress();
return POOL_CONTINUE;
}
+ if (strncasecmp(sq_nodes, string, strlen(sq_nodes)) == 0)
+ {
+ pool_debug("nodes reporting");
+ nodes_reporting(frontend, backend);
+ pool_unset_query_in_progress();
+ return POOL_CONTINUE;
+ }
+
+ if (strncasecmp(sq_version, string, strlen(sq_version)) == 0)
+ {
+ pool_debug("version reporting");
+ version_reporting(frontend, backend);
+ pool_unset_query_in_progress();
+ return POOL_CONTINUE;
+ }
+
/* In this loop,forward the query to the all backends */
for (i=0;i<NUM_BACKENDS;i++)
{
Index: pool_process_reporting.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_process_reporting.c,v
retrieving revision 1.9
diff -c -p -r1.9 pool_process_reporting.c
*** pool_process_reporting.c 21 Jun 2010 05:46:57 -0000 1.9
--- pool_process_reporting.c 5 Aug 2010 12:06:38 -0000
***************
*** 18,34 ****
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
! * Process "show pool_status" query.
*/
#include "pool.h"
#include "pool_proto_modules.h"
#include "pool_stream.h"
#include "pool_config.h"
#include <string.h>
#include <netinet/in.h>
! void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
{
static char *cursorname = "blank";
static short num_fields = 3;
--- 18,90 ----
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
! * Process pgPool-II "SHOW" queries.
*/
#include "pool.h"
#include "pool_proto_modules.h"
#include "pool_stream.h"
#include "pool_config.h"
+ #include "version.h"
#include <string.h>
#include <netinet/in.h>
! /* some length definitions */
! #define POOLCONFIG_MAXNAMELEN 32
! #define POOLCONFIG_MAXVALLEN 512
! #define POOLCONFIG_MAXDESCLEN 64
! #define POOLCONFIG_MAXIDENTLEN 63
! #define POOLCONFIG_MAXPORTLEN 6
! #define POOLCONFIG_MAXSTATLEN 2
! #define POOLCONFIG_MAXWEIGHTLEN 20
! #define POOLCONFIG_MAXDATELEN 20
! #define POOLCONFIG_MAXCOUNTLEN 16
!
! /* config report struct*/
! typedef struct {
! char name[POOLCONFIG_MAXNAMELEN+1];
! char value[POOLCONFIG_MAXVALLEN+1];
! char desc[POOLCONFIG_MAXDESCLEN+1];
! } POOL_REPORT_STATUS;
!
! /* nodes report struct */
! typedef struct {
! char hostname[POOLCONFIG_MAXIDENTLEN+1];
! char port[POOLCONFIG_MAXIDENTLEN+1];
! char status[POOLCONFIG_MAXSTATLEN+1];
! char lb_weight[POOLCONFIG_MAXWEIGHTLEN+1];
! } POOL_REPORT_NODES;
!
! /* processes report struct */
! typedef struct {
! char pool_pid[POOLCONFIG_MAXCOUNTLEN+1];
! char database[POOLCONFIG_MAXIDENTLEN+1];
! char username[POOLCONFIG_MAXIDENTLEN+1];
! char start_time[POOLCONFIG_MAXDATELEN+1];
! char create_time[POOLCONFIG_MAXDATELEN+1];
! char pool_counter[POOLCONFIG_MAXCOUNTLEN+1];
! } POOL_REPORT_PROCESSES;
!
! /* pools reporting struct */
! typedef struct {
! char pool_pid[POOLCONFIG_MAXCOUNTLEN+1];
! char pool_id[POOLCONFIG_MAXCOUNTLEN+1];
! char database[POOLCONFIG_MAXIDENTLEN+1];
! char username[POOLCONFIG_MAXIDENTLEN+1];
! char start_time[POOLCONFIG_MAXDATELEN+1];
! char create_time[POOLCONFIG_MAXDATELEN+1];
! char pool_majorversion[POOLCONFIG_MAXCOUNTLEN+1];
! char pool_minorversion[POOLCONFIG_MAXCOUNTLEN+1];
! char pool_counter[POOLCONFIG_MAXCOUNTLEN+1];
! char pool_backendpid[POOLCONFIG_MAXCOUNTLEN+1];
! } POOL_REPORT_POOLS;
!
! /* version struct */
! typedef struct {
! char version[POOLCONFIG_MAXVALLEN+1];
! } POOL_REPORT_VERSION;
!
! void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
{
static char *cursorname = "blank";
static short num_fields = 3;
*************** void process_reporting(POOL_CONNECTION *
*** 45,60 ****
static unsigned char nullmap[2] = {0xff, 0xff};
int nbytes = (num_fields + 7)/8;
- #define POOLCONFIG_MAXNAMELEN 32
- #define POOLCONFIG_MAXVALLEN 512
- #define POOLCONFIG_MAXDESCLEN 64
-
- typedef struct {
- char name[POOLCONFIG_MAXNAMELEN+1];
- char value[POOLCONFIG_MAXVALLEN+1];
- char desc[POOLCONFIG_MAXDESCLEN+1];
- } POOL_REPORT_STATUS;
-
/*
* Report data buffer.
* 128 is the max number of configuration items.
--- 101,106 ----
*************** void process_reporting(POOL_CONNECTION *
*** 522,528 ****
len += sizeof(int) + strlen(status[i].desc);
len = htonl(len);
pool_write(frontend, &len, sizeof(len));
! s = htons(3);
pool_write(frontend, &s, sizeof(s));
len = htonl(strlen(status[i].name));
--- 568,574 ----
len += sizeof(int) + strlen(status[i].desc);
len = htonl(len);
pool_write(frontend, &len, sizeof(len));
! s = htons(num_fields);
pool_write(frontend, &s, sizeof(s));
len = htonl(strlen(status[i].name));
*************** void process_reporting(POOL_CONNECTION *
*** 559,561 ****
--- 605,1402 ----
pool_flush(frontend);
}
+
+ void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
+ {
+ static char *cursorname = "blank";
+ static short num_fields = 4;
+ static char *field_names[] = {"hostname", "port", "status", "lb_weight"};
+ static int oid = 0;
+ static short fsize = -1;
+ static int mod = 0;
+ short n;
+ int i;
+ short s;
+ int len;
+ short colnum;
+
+ static unsigned char nullmap[2] = {0xff, 0xff};
+ int nbytes = (num_fields + 7)/8;
+
+ POOL_REPORT_NODES nodes[NUM_BACKENDS];
+
+ short nrows;
+ int size;
+ int hsize;
+
+ i = 0;
+
+ char port_str[6];
+ char status[2];
+ char weight_str[20];
+
+ BackendInfo *bi = NULL;
+
+ for (i = 0; i < NUM_BACKENDS; i++)
+ {
+ bi = pool_get_node_info(i);
+
+ strncpy(nodes[i].hostname, bi->backend_hostname, strlen(bi->backend_hostname)+1);
+ snprintf(nodes[i].port, sizeof(port_str), "%d", bi->backend_port);
+ snprintf(nodes[i].status, sizeof(status), "%d", bi->backend_status);
+ snprintf(nodes[i].lb_weight, sizeof(weight_str), "%f", bi->backend_weight);
+ }
+
+ nrows = i;
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* cursor response */
+ pool_write(frontend, "P", 1);
+ pool_write(frontend, cursorname, strlen(cursorname)+1);
+ }
+
+ /* row description */
+ pool_write(frontend, "T", 1);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = sizeof(num_fields) + sizeof(len);
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+ len += strlen(f)+1;
+ len += sizeof(oid);
+ len += sizeof(colnum);
+ len += sizeof(oid);
+ len += sizeof(s);
+ len += sizeof(mod);
+ len += sizeof(s);
+ }
+
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ }
+
+ n = htons(num_fields);
+ pool_write(frontend, &n, sizeof(short));
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+
+ pool_write(frontend, f, strlen(f)+1); /* field name */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ pool_write(frontend, &oid, sizeof(oid)); /* table oid */
+ colnum = htons(i);
+ pool_write(frontend, &colnum, sizeof(colnum)); /* column number */
+ }
+
+ pool_write(frontend, &oid, sizeof(oid)); /* data type oid */
+ s = htons(fsize);
+ pool_write(frontend, &s, sizeof(fsize)); /* field size */
+ pool_write(frontend, &mod, sizeof(mod)); /* modifier */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ s = htons(0);
+ pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */
+ }
+ }
+ pool_flush(frontend);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* ascii row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ pool_write_and_flush(frontend, nullmap, nbytes);
+
+ size = strlen(nodes[i].hostname);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, nodes[i].hostname, size);
+
+ size = strlen(nodes[i].port);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, nodes[i].port, size);
+
+ size = strlen(nodes[i].status);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, nodes[i].status, size);
+
+ size = strlen(nodes[i].lb_weight);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, nodes[i].lb_weight, size);
+ }
+ }
+ else
+ {
+ /* data row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ len = sizeof(len) + sizeof(nrows);
+ len += sizeof(int) + strlen(nodes[i].hostname);
+ len += sizeof(int) + strlen(nodes[i].port);
+ len += sizeof(int) + strlen(nodes[i].status);
+ len += sizeof(int) + strlen(nodes[i].lb_weight);
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ s = htons(num_fields);
+ pool_write(frontend, &s, sizeof(s));
+
+ len = htonl(strlen(nodes[i].hostname));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, nodes[i].hostname, strlen(nodes[i].hostname));
+
+ len = htonl(strlen(nodes[i].port));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, nodes[i].port, strlen(nodes[i].port));
+
+ len = htonl(strlen(nodes[i].status));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, nodes[i].status, strlen(nodes[i].status));
+
+ len = htonl(strlen(nodes[i].lb_weight));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, nodes[i].lb_weight, strlen(nodes[i].lb_weight));
+ }
+ }
+
+ /* complete command response */
+ pool_write(frontend, "C", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + strlen("SELECT")+1);
+ pool_write(frontend, &len, sizeof(len));
+ }
+ pool_write(frontend, "SELECT", strlen("SELECT")+1);
+
+ /* ready for query */
+ pool_write(frontend, "Z", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + 1);
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, "I", 1);
+ }
+
+ pool_flush(frontend);
+ }
+
+ void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
+ {
+ static char *cursorname = "blank";
+ static short num_fields = 10;
+ static char *field_names[] = {"pool_pid", "pool_id", "database", "username", "start_time", "create_time",
+ "majorversion", "minorversion", "pool_counter", "pool_backendpid"};
+ static int oid = 0;
+ static short fsize = -1;
+ static int mod = 0;
+ short n;
+ int i, j;
+ short s;
+ int len;
+ short colnum;
+
+ static unsigned char nullmap[2] = {0xff, 0xff};
+ int nbytes = (num_fields + 7)/8;
+
+ POOL_REPORT_POOLS pools[MAX_NUM_BACKENDS * pool_config->max_pool];
+
+ short nrows;
+ int size;
+ int hsize;
+
+ i = 0;
+
+ ProcessInfo *pi = NULL;
+ int proc_id;
+
+ int k = 0;
+ for (i = 0; i < pool_config->num_init_children; i++)
+ {
+ proc_id = process_info[i].pid;
+ pi = pool_get_process_info(proc_id);
+
+ for (j=0;j<pool_config->max_pool;j++)
+ {
+ snprintf(pools[k].pool_pid, POOLCONFIG_MAXCOUNTLEN, "%d", proc_id);
+ snprintf(pools[k].pool_id, POOLCONFIG_MAXCOUNTLEN, "%d", j);
+ strncpy(pools[k].database, pi->connection_info[j].database, POOLCONFIG_MAXIDENTLEN);
+ strncpy(pools[k].username, pi->connection_info[j].user, POOLCONFIG_MAXIDENTLEN);
+ snprintf(pools[k].start_time, POOLCONFIG_MAXDATELEN, "%ld", pi->start_time);
+ snprintf(pools[k].create_time, POOLCONFIG_MAXDATELEN, "%ld", pi->connection_info[j].create_time);
+ snprintf(pools[k].pool_majorversion, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[i].major);
+ snprintf(pools[k].pool_minorversion, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[i].minor);
+ snprintf(pools[k].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[j].counter);
+ snprintf(pools[k].pool_backendpid, POOLCONFIG_MAXCOUNTLEN, "%d", ntohl(pi->connection_info[j].pid));
+ k++;
+ }
+ }
+
+ nrows = k;
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* cursor response */
+ pool_write(frontend, "P", 1);
+ pool_write(frontend, cursorname, strlen(cursorname)+1);
+ }
+
+ /* row description */
+ pool_write(frontend, "T", 1);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = sizeof(num_fields) + sizeof(len);
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+ len += strlen(f)+1;
+ len += sizeof(oid);
+ len += sizeof(colnum);
+ len += sizeof(oid);
+ len += sizeof(s);
+ len += sizeof(mod);
+ len += sizeof(s);
+ }
+
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ }
+
+ n = htons(num_fields);
+ pool_write(frontend, &n, sizeof(short));
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+
+ pool_write(frontend, f, strlen(f)+1); /* field name */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ pool_write(frontend, &oid, sizeof(oid)); /* table oid */
+ colnum = htons(i);
+ pool_write(frontend, &colnum, sizeof(colnum)); /* column number */
+ }
+
+ pool_write(frontend, &oid, sizeof(oid)); /* data type oid */
+ s = htons(fsize);
+ pool_write(frontend, &s, sizeof(fsize)); /* field size */
+ pool_write(frontend, &mod, sizeof(mod)); /* modifier */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ s = htons(0);
+ pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */
+ }
+ }
+ pool_flush(frontend);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* ascii row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ pool_write_and_flush(frontend, nullmap, nbytes);
+
+ size = strlen(pools[i].pool_pid);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_pid, size);
+
+ size = strlen(pools[i].pool_id);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_id, size);
+
+ size = strlen(pools[i].database);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].database, size);
+
+ size = strlen(pools[i].username);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].username, size);
+
+ size = strlen(pools[i].start_time);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].start_time, size);
+
+ size = strlen(pools[i].create_time);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].create_time, size);
+
+ size = strlen(pools[i].pool_majorversion);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_majorversion, size);
+
+ size = strlen(pools[i].pool_minorversion);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_minorversion, size);
+
+ size = strlen(pools[i].pool_counter);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_counter, size);
+
+ size = strlen(pools[i].pool_backendpid);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[i].pool_backendpid, size);
+ }
+ }
+ else
+ {
+ /* data row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ len = sizeof(len) + sizeof(nrows);
+ len += sizeof(int) + strlen(pools[i].pool_pid);
+ len += sizeof(int) + strlen(pools[i].pool_id);
+ len += sizeof(int) + strlen(pools[i].database);
+ len += sizeof(int) + strlen(pools[i].username);
+ len += sizeof(int) + strlen(pools[i].start_time);
+ len += sizeof(int) + strlen(pools[i].create_time);
+ len += sizeof(int) + strlen(pools[i].pool_majorversion);
+ len += sizeof(int) + strlen(pools[i].pool_minorversion);
+ len += sizeof(int) + strlen(pools[i].pool_counter);
+ len += sizeof(int) + strlen(pools[i].pool_backendpid);
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ s = htons(num_fields);
+ pool_write(frontend, &s, sizeof(s));
+
+ len = htonl(strlen(pools[i].pool_pid));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_pid, strlen(pools[i].pool_pid));
+
+ len = htonl(strlen(pools[i].pool_id));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_id, strlen(pools[i].pool_id));
+
+ len = htonl(strlen(pools[i].database));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].database, strlen(pools[i].database));
+
+ len = htonl(strlen(pools[i].username));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].username, strlen(pools[i].username));
+
+ len = htonl(strlen(pools[i].start_time));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].start_time, strlen(pools[i].start_time));
+
+ len = htonl(strlen(pools[i].create_time));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].create_time, strlen(pools[i].create_time));
+
+ len = htonl(strlen(pools[i].pool_majorversion));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_majorversion, strlen(pools[i].pool_majorversion));
+
+ len = htonl(strlen(pools[i].pool_minorversion));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_minorversion, strlen(pools[i].pool_minorversion));
+
+ len = htonl(strlen(pools[i].pool_counter));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_counter, strlen(pools[i].pool_counter));
+
+ len = htonl(strlen(pools[i].pool_backendpid));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_backendpid, strlen(pools[i].pool_backendpid));
+ }
+ }
+
+ /* complete command response */
+ pool_write(frontend, "C", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + strlen("SELECT")+1);
+ pool_write(frontend, &len, sizeof(len));
+ }
+ pool_write(frontend, "SELECT", strlen("SELECT")+1);
+
+ /* ready for query */
+ pool_write(frontend, "Z", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + 1);
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, "I", 1);
+ }
+
+ pool_flush(frontend);
+ }
+
+ void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
+ {
+ static char *cursorname = "blank";
+ static short num_fields = 6;
+ static char *field_names[] = {"pool_pid", "database", "username", "start_time", "create_time", "pool_counter"};
+ static int oid = 0;
+ static short fsize = -1;
+ static int mod = 0;
+ short n;
+ int i;
+ short s;
+ int len;
+ short colnum;
+
+ static unsigned char nullmap[2] = {0xff, 0xff};
+ int nbytes = (num_fields + 7)/8;
+
+ static POOL_REPORT_PROCESSES processes[MAX_NUM_BACKENDS];
+
+ short nrows;
+ int size;
+ int hsize;
+
+ i = 0;
+
+ ProcessInfo *pi = NULL;
+ int proc_id;
+
+ for (i = 0; i < pool_config->num_init_children; i++)
+ {
+ proc_id = process_info[i].pid;
+ pi = pool_get_process_info(proc_id);
+
+ snprintf(processes[i].pool_pid, POOLCONFIG_MAXCOUNTLEN, "%d", proc_id);
+ strncpy(processes[i].database, pi->connection_info[0].database, POOLCONFIG_MAXIDENTLEN);
+ strncpy(processes[i].username, pi->connection_info[0].user, POOLCONFIG_MAXIDENTLEN);
+ snprintf(processes[i].start_time, POOLCONFIG_MAXDATELEN, "%ld", pi->start_time);
+ snprintf(processes[i].create_time, POOLCONFIG_MAXDATELEN, "%ld", pi->connection_info[0].create_time);
+ //snprintf(majorversion, sizeof(majorversion), "%d", pi->connection_info[i].major);
+ //snprintf(minorversion, sizeof(minorversion), "%d", pi->connection_info[i].minor);
+ snprintf(processes[i].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[0].counter);
+ }
+
+ nrows = i;
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* cursor response */
+ pool_write(frontend, "P", 1);
+ pool_write(frontend, cursorname, strlen(cursorname)+1);
+ }
+
+ /* row description */
+ pool_write(frontend, "T", 1);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = sizeof(num_fields) + sizeof(len);
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+ len += strlen(f)+1;
+ len += sizeof(oid);
+ len += sizeof(colnum);
+ len += sizeof(oid);
+ len += sizeof(s);
+ len += sizeof(mod);
+ len += sizeof(s);
+ }
+
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ }
+
+ n = htons(num_fields);
+ pool_write(frontend, &n, sizeof(short));
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+
+ pool_write(frontend, f, strlen(f)+1); /* field name */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ pool_write(frontend, &oid, sizeof(oid)); /* table oid */
+ colnum = htons(i);
+ pool_write(frontend, &colnum, sizeof(colnum)); /* column number */
+ }
+
+ pool_write(frontend, &oid, sizeof(oid)); /* data type oid */
+ s = htons(fsize);
+ pool_write(frontend, &s, sizeof(fsize)); /* field size */
+ pool_write(frontend, &mod, sizeof(mod)); /* modifier */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ s = htons(0);
+ pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */
+ }
+ }
+ pool_flush(frontend);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* ascii row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ pool_write_and_flush(frontend, nullmap, nbytes);
+
+ size = strlen(processes[i].pool_pid);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].pool_pid, size);
+
+ size = strlen(processes[i].database);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].database, size);
+
+ size = strlen(processes[i].username);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].username, size);
+
+ size = strlen(processes[i].start_time);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].start_time, size);
+
+ size = strlen(processes[i].create_time);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].create_time, size);
+
+ size = strlen(processes[i].pool_counter);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, processes[i].pool_counter, size);
+ }
+ }
+ else
+ {
+ /* data row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ len = sizeof(len) + sizeof(nrows);
+ len += sizeof(int) + strlen(processes[i].pool_pid);
+ len += sizeof(int) + strlen(processes[i].database);
+ len += sizeof(int) + strlen(processes[i].username);
+ len += sizeof(int) + strlen(processes[i].start_time);
+ len += sizeof(int) + strlen(processes[i].create_time);
+ len += sizeof(int) + strlen(processes[i].pool_counter);
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ s = htons(num_fields);
+ pool_write(frontend, &s, sizeof(s));
+
+ len = htonl(strlen(processes[i].pool_pid));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].pool_pid, strlen(processes[i].pool_pid));
+
+ len = htonl(strlen(processes[i].database));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].database, strlen(processes[i].database));
+
+ len = htonl(strlen(processes[i].username));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].username, strlen(processes[i].username));
+
+ len = htonl(strlen(processes[i].start_time));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].start_time, strlen(processes[i].start_time));
+
+ len = htonl(strlen(processes[i].create_time));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].create_time, strlen(processes[i].create_time));
+
+ len = htonl(strlen(processes[i].pool_counter));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, processes[i].pool_counter, strlen(processes[i].pool_counter));
+ }
+ }
+
+ /* complete command response */
+ pool_write(frontend, "C", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + strlen("SELECT")+1);
+ pool_write(frontend, &len, sizeof(len));
+ }
+ pool_write(frontend, "SELECT", strlen("SELECT")+1);
+
+ /* ready for query */
+ pool_write(frontend, "Z", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + 1);
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, "I", 1);
+ }
+
+ pool_flush(frontend);
+ }
+
+ void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
+ {
+ static char *cursorname = "blank";
+ static short num_fields = 1;
+ static char *field_names[] = {"pool_version"};
+ static int oid = 0;
+ static short fsize = -1;
+ static int mod = 0;
+ short n;
+ int i;
+ short s;
+ int len;
+ short colnum;
+
+ static unsigned char nullmap[2] = {0xff, 0xff};
+ int nbytes = (num_fields + 7)/8;
+
+ /*
+ * Report data buffer.
+ * 1 for the version
+ */
+ static POOL_REPORT_VERSION version[1];
+
+ short nrows;
+ int size;
+ int hsize;
+
+ snprintf(version[0].version, POOLCONFIG_MAXVALLEN, "%s (%s)", VERSION, PGPOOLVERSION);
+
+ nrows = 1;
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* cursor response */
+ pool_write(frontend, "P", 1);
+ pool_write(frontend, cursorname, strlen(cursorname)+1);
+ }
+
+ /* row description */
+ pool_write(frontend, "T", 1);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = sizeof(num_fields) + sizeof(len);
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+ len += strlen(f)+1;
+ len += sizeof(oid);
+ len += sizeof(colnum);
+ len += sizeof(oid);
+ len += sizeof(s);
+ len += sizeof(mod);
+ len += sizeof(s);
+ }
+
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ }
+
+ n = htons(num_fields);
+ pool_write(frontend, &n, sizeof(short));
+
+ for (i=0;i<num_fields;i++)
+ {
+ char *f = field_names[i];
+
+ pool_write(frontend, f, strlen(f)+1); /* field name */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ pool_write(frontend, &oid, sizeof(oid)); /* table oid */
+ colnum = htons(i);
+ pool_write(frontend, &colnum, sizeof(colnum)); /* column number */
+ }
+
+ pool_write(frontend, &oid, sizeof(oid)); /* data type oid */
+ s = htons(fsize);
+ pool_write(frontend, &s, sizeof(fsize)); /* field size */
+ pool_write(frontend, &mod, sizeof(mod)); /* modifier */
+
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ s = htons(0);
+ pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */
+ }
+ }
+ pool_flush(frontend);
+
+ if (MAJOR(backend) == PROTO_MAJOR_V2)
+ {
+ /* ascii row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ pool_write_and_flush(frontend, nullmap, nbytes);
+
+ size = strlen(version[i].version);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, version[i].version, size);
+ }
+ }
+ else
+ {
+ /* data row */
+ for (i=0;i<nrows;i++)
+ {
+ pool_write(frontend, "D", 1);
+ len = sizeof(len) + sizeof(nrows);
+ len += sizeof(int) + strlen(version[i].version);
+ len = htonl(len);
+ pool_write(frontend, &len, sizeof(len));
+ s = htons(num_fields);
+ pool_write(frontend, &s, sizeof(s));
+
+ len = htonl(strlen(version[i].version));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, version[i].version, strlen(version[i].version));
+ }
+ }
+
+ /* complete command response */
+ pool_write(frontend, "C", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + strlen("SELECT")+1);
+ pool_write(frontend, &len, sizeof(len));
+ }
+ pool_write(frontend, "SELECT", strlen("SELECT")+1);
+
+ /* ready for query */
+ pool_write(frontend, "Z", 1);
+ if (MAJOR(backend) == PROTO_MAJOR_V3)
+ {
+ len = htonl(sizeof(len) + 1);
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, "I", 1);
+ }
+
+ pool_flush(frontend);
+ }
+
Index: pool_proto_modules.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_proto_modules.c,v
retrieving revision 1.74
diff -c -p -r1.74 pool_proto_modules.c
*** pool_proto_modules.c 4 Aug 2010 02:58:38 -0000 1.74
--- pool_proto_modules.c 5 Aug 2010 12:06:38 -0000
*************** static int* find_victim_nodes(int *ntupl
*** 106,112 ****
POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
POOL_CONNECTION_POOL *backend, int len, char *contents)
{
! static char *sq = "show pool_status";
int commit;
List *parse_tree_list;
Node *node = NULL;
--- 106,116 ----
POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
POOL_CONNECTION_POOL *backend, int len, char *contents)
{
! static char *sq_config = "show pool_status";
! static char *sq_pools = "show pool_pools";
! static char *sq_processes = "show pool_processes";
! static char *sq_nodes = "show pool_nodes";
! static char *sq_version = "show pool_version";
int commit;
List *parse_tree_list;
Node *node = NULL;
*************** POOL_STATUS SimpleQuery(POOL_CONNECTION
*** 235,248 ****
}
}
! /* process status reporting? */
! if (IsA(node, VariableShowStmt) && strncasecmp(sq, contents, strlen(sq)) == 0)
{
StartupPacket *sp;
char psbuf[1024];
! pool_debug("process reporting");
! process_reporting(frontend, backend);
/* show ps status */
sp = MASTER_CONNECTION(backend)->sp;
--- 239,279 ----
}
}
! /* status reporting? */
! if ((IsA(node, VariableShowStmt) && strncasecmp(sq_config, contents, strlen(sq_config)) == 0)
! || (IsA(node, VariableShowStmt) && strncasecmp(sq_pools, contents, strlen(sq_pools)) == 0)
! || (IsA(node, VariableShowStmt) && strncasecmp(sq_processes, contents, strlen(sq_processes)) == 0)
! || (IsA(node, VariableShowStmt) && strncasecmp(sq_nodes, contents, strlen(sq_nodes)) == 0)
! || (IsA(node, VariableShowStmt) && strncasecmp(sq_version, contents, strlen(sq_version)) == 0))
{
StartupPacket *sp;
char psbuf[1024];
! if (strncasecmp(sq_config, contents, strlen(sq_config)) == 0)
! {
! pool_debug("config reporting");
! config_reporting(frontend, backend);
! }
! else if (strncasecmp(sq_pools, contents, strlen(sq_pools)) == 0)
! {
! pool_debug("pools reporting");
! pools_reporting(frontend, backend);
! }
! else if (strncasecmp(sq_processes, contents, strlen(sq_processes)) == 0)
! {
! pool_debug("processes reporting");
! processes_reporting(frontend, backend);
! }
! else if (strncasecmp(sq_nodes, contents, strlen(sq_nodes)) == 0)
! {
! pool_debug("nodes reporting");
! nodes_reporting(frontend, backend);
! }
! else if (strncasecmp(sq_version, contents, strlen(sq_version)) == 0)
! {
! pool_debug("version reporting");
! version_reporting(frontend, backend);
! }
/* show ps status */
sp = MASTER_CONNECTION(backend)->sp;
Index: pool_proto_modules.h
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_proto_modules.h,v
retrieving revision 1.17
diff -c -p -r1.17 pool_proto_modules.h
*** pool_proto_modules.h 4 Aug 2010 02:58:38 -0000 1.17
--- pool_proto_modules.h 5 Aug 2010 12:06:38 -0000
*************** extern bool is_partition_table(POOL_CONN
*** 174,180 ****
extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp);
extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP DATABASE command */
! extern void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
extern POOL_STATUS send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major);
extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend,
--- 174,184 ----
extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp);
extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP DATABASE command */
! extern void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
! extern void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
! extern void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
! extern void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
! extern void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
extern POOL_STATUS send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major);
extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend,
_______________________________________________
Pgpool-hackers mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-hackers