1 /* -*-pgsql-c-*- */
2 /*
3  *
4  * $Header$
5  *
6  * pgpool: a language independent connection pool server for PostgreSQL
7  * written by Tatsuo Ishii
8  *
9  * Copyright (c) 2003-2014	PgPool Global Development Group
10  *
11  */
12 /*--------------------------------------------------------------------
13  * statistics.c
14  *
15  * Various statistics related functions.
16  *--------------------------------------------------------------------
17  */
18 
19 #include <unistd.h>
20 #include <string.h>
21 
22 #include "pool.h"
23 #include "parser/nodes.h"
24 
25 /*
26  * Per backend node stat area in shared memory
27  */
28 typedef struct
29 {
30 	uint64		select_cnt;		/* number of read SELECT queries issued */
31 	uint64		insert_cnt;		/* number of INSERT queries issued */
32 	uint64		update_cnt;		/* number of UPDATE queries issued */
33 	uint64		delete_cnt;		/* number of DELETE queries issued */
34 	uint64		ddl_cnt;		/* number of DDL queries issued */
35 	uint64		other_cnt;		/* number of any other queries issued */
36 }			PER_NODE_STAT;
37 
38 static volatile PER_NODE_STAT *per_node_stat;
39 
40 /*
41  * Return shared memory size necessary for this module
42  */
43 size_t
stat_shared_memory_size(void)44 stat_shared_memory_size(void)
45 {
46 	size_t		size;
47 
48 	/* query counter area */
49 	size = MAXALIGN(MAX_NUM_BACKENDS * sizeof(PER_NODE_STAT));
50 
51 	return size;
52 }
53 
54 /*
55  * Set PER_NODE_STAT address in the shared memory area to global variable.
56  * This should be called from pgpool main process upon startup.
57  */
58 void
stat_set_stat_area(void * address)59 stat_set_stat_area(void *address)
60 {
61 	per_node_stat = (PER_NODE_STAT *) address;
62 }
63 
64 /*
65  * Initialize shared memory stat area
66  */
67 void
stat_init_stat_area(void)68 stat_init_stat_area(void)
69 {
70 	memset((void *) per_node_stat, 0, stat_shared_memory_size());
71 }
72 
73 /*
74  * Update stat counter
75  */
76 void
stat_count_up(int backend_node_id,Node * parse_tree)77 stat_count_up(int backend_node_id, Node *parse_tree)
78 {
79 	if (parse_tree == NULL)
80 	{
81 		/*
82 		 * No parse tree. does not worth to gather statistics (internal
83 		 * queries).  If we want to gather statistics for queries without
84 		 * parse tree, we could call the parser but I don't think it's worth
85 		 * the trouble.
86 		 */
87 		return;
88 	}
89 
90 	if (IsA(parse_tree, SelectStmt))
91 	{
92 		per_node_stat[backend_node_id].select_cnt++;
93 	}
94 }
95 
96 /*
97  * Stat counter read functions
98  */
99 uint64
stat_get_select_count(int backend_node_id)100 stat_get_select_count(int backend_node_id)
101 {
102 	return per_node_stat[backend_node_id].select_cnt;
103 }
104