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 Pgpool-hackers@pgfoundry.org http://pgfoundry.org/mailman/listinfo/pgpool-hackers