Le 22/07/2010 00:07, Guillaume Lelarge a écrit :
> Le 21/07/2010 10:11, Tatsuo Ishii a écrit :
>>>> I would add pgsql_pid to pcp_proc_info anyway but in the mean time I
>>>> understand your concern about pcp API (it's a shame that libppcp API
>>>> is not documented anywhere BTW).
>>>
>>> OK, that would be good to have (the psql_pid column).
>>>
>>>> I admit that SELECT or SHOW is easier to use for appIications such as
>>>> pgAdmin. So I do not object to add new SELECT or SHOW command you
>>>> proposed. Would you like to create patches for this?
>>>
>>> Yeah, I will work on it right away. My patches for pgAdmin can wait, but
>>> the one for pgPool can't if you want to get a release out at the end of the
>>> month. I can also work on the documentation for the libppcp API. But first,
>>> the SHOW statement.
>>
>> Great. I and Kitagawa are working hard but it seems the actual release
>> timing delays... like mid of August. Probably submitting by the end of
>> July is enough.
>
> OK, no problem.
>
> I worked a bit on it tonight. I began with something really simple:
> "show pool_version". And it works :)
>
> guilla...@laptop:~/freeprojects/cvs.pgpool/head/pgpool-II$ psql -p 9999
> postgres
> psql (9.0beta3)
> Saisissez « help » pour l'aide.
>
> postgres=# show pool_version;
> pool_version
> ------------------------
> 3.0-dev (umiyameboshi)
> (1 ligne)
>
>
> Next "show pool_processes", and "show pools". Not really sure if I need
> to make a difference.
>
OK, here is my WIP patch. I send it to get advice, comments, in order to
finish it.
The patch attached handles four more SHOW commands. Of course, "SHOW
pool_status" is still available.
"SHOW pool_version" shows the version of pgPool-II:
postgres=# show pool_version;
pool_version
------------------------
3.0-dev (umiyameboshi)
(1 row)
"SHOW pool_nodes" shows every configured nodes:
postgres=# show pool_nodes;
hostname | port | status | lb_weight
-----------+------+--------+-------------------
127.0.0.1 | 5432 | 2 | 2147483647.000000
(1 row)
"SHOW pool_processes" shows every process of pgPool-II:
postgres=# SHOW pool_processes;
pool_pid | database | username | start_time | create_time | pool_counter
----------+----------+-----------+------------+-------------+--------------
4918 | | | 1280061734 | 0 | 0
[... cut ...]
4923 | | | 1280061734 | 0 | 0
4924 | b1 | guillaume | 1280061734 | 1280061768 | 1
4925 | b1 | guillaume | 1280061734 | 1280061915 | 1
4926 | | | 1280061734 | 0 | 0
4927 | | | 1280061734 | 0 | 0
4928 | b1 | guillaume | 1280061734 | 1280061750 | 2
4929 | | | 1280061734 | 0 | 0
4930 | postgres | guillaume | 1280061734 | 1280061798 | 1
4931 | | | 1280061734 | 0 | 0
[... cut ...]
4939 | | | 1280061734 | 0 | 0
4940 | b1 | guillaume | 1280061734 | 1280061914 | 1
4941 | | | 1280061734 | 0 | 0
[... cut ...]
4948 | | | 1280061734 | 0 | 0
4949 | b2 | guillaume | 1280061734 | 1280061755 | 1
(32 rows)
And finally, "SHOW pools", which shows every connection to PostgreSQL,
active or not:
postgres=# SHOW pool_pools;
pool_pid | pool_id | database | username | start_time | create_time |
pool_counter
----------+---------+----------+-----------+------------+-------------+--------------
[... cut ...]
4923 | 0 | | | 1280061734 | 0 | 0
4923 | 1 | | | 1280061734 | 0 | 0
4923 | 2 | | | 1280061734 | 0 | 0
4923 | 3 | | | 1280061734 | 0 | 0
4924 | 0 | b1 | guillaume | 1280061734 | 1280061768 | 1
4924 | 1 | | | 1280061734 | 0 | 0
4924 | 2 | | | 1280061734 | 0 | 0
4924 | 3 | | | 1280061734 | 0 | 0
4925 | 0 | b1 | guillaume | 1280061734 | 1280061915 | 1
4925 | 1 | | | 1280061734 | 0 | 0
4925 | 2 | | | 1280061734 | 0 | 0
4925 | 3 | | | 1280061734 | 0 | 0
[... cut ...]
4928 | 0 | b1 | guillaume | 1280061734 | 1280061750 | 2
4928 | 1 | | | 1280061734 | 0 | 0
[... cut ...]
4929 | 3 | | | 1280061734 | 0 | 0
4930 | 0 | postgres | guillaume | 1280061734 | 1280061798 | 1
4930 | 1 | | | 1280061734 | 0 |
[... cut ...]
0
4939 | 3 | | | 1280061734 | 0 | 0
4940 | 0 | b1 | guillaume | 1280061734 | 1280061914 | 1
4940 | 1 | | | 1280061734 | 0 |
[... cut ...]
4948 | 3 | | | 1280061734 | 0 | 0
4949 | 0 | b2 | guillaume | 1280061734 | 1280061755 | 1
4949 | 1 | | | 1280061734 | 0 | 0
4949 | 2 | | | 1280061734 | 0 | 0
4949 | 3 | | | 1280061734 | 0 | 0
(128 rows)
AFAICT, it works really good. We still miss pgsql_pid. And should I add
some other reports? what do other people need?
--
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.228
diff -c -p -r1.228 pool_process_query.c
*** pool_process_query.c 23 Jul 2010 06:54:34 -0000 1.228
--- pool_process_query.c 25 Jul 2010 12:39:22 -0000
*************** POOL_STATUS pool_parallel_exec(POOL_CONN
*** 460,466 ****
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;
--- 460,470 ----
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
*** 487,500 ****
}
/* 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++)
{
--- 491,536 ----
}
/* 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 25 Jul 2010 12:39:23 -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,87 ----
* 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_counter[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.
--- 98,103 ----
*************** 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));
--- 565,571 ----
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 ****
--- 602,1377 ----
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 = 7;
+ static char *field_names[] = {"pool_pid", "pool_id", "database", "username", "start_time", "create_time", "pool_counter"};
+ 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;
+
+ /*
+ char majorversion[5];
+ char minorversion[5];
+ */
+
+ 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(majorversion, sizeof(majorversion), "%d", pi->connection_info[i].major);
+ //snprintf(minorversion, sizeof(minorversion), "%d", pi->connection_info[i].minor);
+ snprintf(pools[k].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[j].counter);
+ 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_counter);
+ hsize = htonl(size+4);
+ pool_write(frontend, &hsize, sizeof(hsize));
+ pool_write(frontend, pools[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(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_counter);
+ 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_counter));
+ pool_write(frontend, &len, sizeof(len));
+ pool_write(frontend, pools[i].pool_counter, strlen(pools[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 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;
+
+ /*
+ char majorversion[5];
+ char minorversion[5];
+ */
+
+ 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.68
diff -c -p -r1.68 pool_proto_modules.c
*** pool_proto_modules.c 23 Jul 2010 06:08:33 -0000 1.68
--- pool_proto_modules.c 25 Jul 2010 12:39:24 -0000
*************** static int* find_victim_nodes(int *ntupl
*** 110,116 ****
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;
--- 110,120 ----
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
*** 239,252 ****
}
}
! /* 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;
--- 243,283 ----
}
}
! /* 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.15
diff -c -p -r1.15 pool_proto_modules.h
*** pool_proto_modules.h 22 Jul 2010 04:24:34 -0000 1.15
--- pool_proto_modules.h 25 Jul 2010 12:39:24 -0000
*************** extern bool is_partition_table(POOL_CONN
*** 177,183 ****
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,
--- 177,187 ----
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