Use AC_PROG_INSTALL & ./install-sh
[pgbouncer.git] / include / bouncer.h
blob8f46a4511bc3eae77a22fc930e83b557f0768a2d
1 /*
2 * PgBouncer - Lightweight connection pooler for PostgreSQL.
3 *
4 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * core structures
23 #include "system.h"
25 #include <event.h>
27 #ifdef DBGVER
28 #define FULLVER PACKAGE_NAME " version " PACKAGE_VERSION " (" DBGVER ")"
29 #else
30 #define FULLVER PACKAGE_NAME " version " PACKAGE_VERSION
31 #endif
33 /* each state corresponts to a list */
34 enum SocketState {
35 CL_FREE, /* free_client_list */
36 CL_JUSTFREE, /* justfree_client_list */
37 CL_LOGIN, /* login_client_list */
38 CL_WAITING, /* pool->waiting_client_list */
39 CL_ACTIVE, /* pool->active_client_list */
40 CL_CANCEL, /* pool->cancel_req_list */
42 SV_FREE, /* free_server_list */
43 SV_JUSTFREE, /* justfree_server_list */
44 SV_LOGIN, /* pool->new_server_list */
45 SV_IDLE, /* pool->idle_server_list */
46 SV_ACTIVE, /* pool->active_server_list */
47 SV_USED, /* pool->used_server_list */
48 SV_TESTED /* pool->tested_server_list */
51 enum PauseMode {
52 P_NONE = 0, /* active pooling */
53 P_PAUSE = 1, /* wait for client to finish work */
54 P_SUSPEND = 2 /* wait for buffers to be empty */
57 #define is_server_socket(sk) ((sk)->state >= SV_FREE)
60 typedef struct PgSocket PgSocket;
61 typedef struct PgUser PgUser;
62 typedef struct PgDatabase PgDatabase;
63 typedef struct PgPool PgPool;
64 typedef struct PgStats PgStats;
65 typedef struct PgAddr PgAddr;
66 typedef enum SocketState SocketState;
67 typedef struct PktHdr PktHdr;
69 extern int cf_sbuf_len;
71 #include "aatree.h"
72 #include "hash.h"
73 #include "util.h"
74 #include "list.h"
75 #include "mbuf.h"
76 #include "iobuf.h"
77 #include "sbuf.h"
78 #include "pktbuf.h"
79 #include "varcache.h"
80 #include "slab.h"
82 #include "admin.h"
83 #include "loader.h"
84 #include "client.h"
85 #include "server.h"
86 #include "pooler.h"
87 #include "proto.h"
88 #include "objects.h"
89 #include "stats.h"
90 #include "takeover.h"
91 #include "janitor.h"
93 /* to avoid allocations will use static buffers */
94 #define MAX_DBNAME 64
95 #define MAX_USERNAME 64
96 #define MAX_PASSWORD 64
98 /* auth modes, should match PG's */
99 #define AUTH_ANY -1 /* same as trust but without username check */
100 #define AUTH_TRUST 0
101 #define AUTH_PLAIN 3
102 #define AUTH_CRYPT 4
103 #define AUTH_MD5 5
104 #define AUTH_CREDS 6
106 /* type codes for weird pkts */
107 #define PKT_STARTUP_V2 0x20000
108 #define PKT_STARTUP 0x30000
109 #define PKT_CANCEL 80877102
110 #define PKT_SSLREQ 80877103
112 #define POOL_SESSION 0
113 #define POOL_TX 1
114 #define POOL_STMT 2
116 /* old style V2 header: len:4b code:4b */
117 #define OLD_HEADER_LEN 8
118 /* new style V3 packet header len - type:1b, len:4b */
119 #define NEW_HEADER_LEN 5
121 #define BACKENDKEY_LEN 8
123 /* buffer size for startup noise */
124 #define STARTUP_BUF 1024
127 * Remote/local address
129 struct PgAddr {
130 struct in_addr ip_addr;
131 unsigned short port;
132 bool is_unix;
136 * Stats, kept per-pool.
138 struct PgStats {
139 uint64_t request_count;
140 uint64_t server_bytes;
141 uint64_t client_bytes;
142 usec_t query_time; /* total req time in us */
146 * Contains connections for one db+user pair.
148 * Stats:
149 * ->stats is updated online.
150 * for each stats_period:
151 * ->older_stats = ->newer_stats
152 * ->newer_stats = ->stats
154 struct PgPool {
155 List head; /* entry in global pool_list */
156 List map_head; /* entry in user->pool_list */
158 PgDatabase *db; /* corresponging database */
159 PgUser *user; /* user logged in as */
161 StatList active_client_list; /* waiting events logged in clients */
162 StatList waiting_client_list; /* client waits for a server to be available */
163 StatList cancel_req_list; /* closed client connections with server key */
165 StatList active_server_list; /* servers linked with clients */
166 StatList idle_server_list; /* servers ready to be linked with clients */
167 StatList used_server_list; /* server just unlinked from clients */
168 StatList tested_server_list; /* server in testing process */
169 StatList new_server_list; /* servers in login phase */
171 PgStats stats;
172 PgStats newer_stats;
173 PgStats older_stats;
175 /* database info to be sent to client */
176 uint8_t welcome_msg[STARTUP_BUF]; /* ServerParams without VarCache ones */
177 unsigned welcome_msg_len;
179 VarCache orig_vars; /* default params from server */
181 usec_t last_lifetime_disconnect;/* last time when server_lifetime was applied */
183 /* if last connect failed, there should be delay before next */
184 usec_t last_connect_time;
185 unsigned last_connect_failed:1;
187 unsigned welcome_msg_ready:1;
190 #define pool_server_count(pool) ( \
191 statlist_count(&(pool)->active_server_list) + \
192 statlist_count(&(pool)->idle_server_list) + \
193 statlist_count(&(pool)->new_server_list) + \
194 statlist_count(&(pool)->tested_server_list) + \
195 statlist_count(&(pool)->used_server_list))
197 #define pool_client_count(pool) ( \
198 statlist_count(&(pool)->active_client_list) + \
199 statlist_count(&(pool)->waiting_client_list))
202 * A user in login db.
204 * fixme: remove ->head as ->tree_node should be enough.
206 * For databases where remote user is forced, the pool is:
207 * first(db->forced_user->pool_list), where pool_list has only one entry.
209 * Otherwise, ->pool_list contains multiple pools, for all PgDatabases
210 * whis user has logged in.
212 struct PgUser {
213 List head; /* used to attach user to list */
214 List pool_list; /* list of pools where pool->user == this user */
215 Node tree_node; /* used to attach user to tree */
216 char name[MAX_USERNAME];
217 char passwd[MAX_PASSWORD];
221 * A database entry from config.
223 struct PgDatabase {
224 List head;
225 char name[MAX_DBNAME]; /* db name for clients */
227 bool db_paused; /* PAUSE <db>; was issued */
228 bool db_dead; /* used on RELOAD/SIGHUP to later detect removed dbs */
229 bool db_auto; /* is the database auto-created by autodb_connstr */
230 bool admin; /* internal console db */
232 uint8_t startup_params[STARTUP_BUF]; /* partial StartupMessage (without user) be sent to server */
233 unsigned startup_params_len;
235 PgUser *forced_user; /* if not NULL, the user/psw is forced */
237 PgAddr addr; /* address prepared for connect() */
238 char unix_socket_dir[UNIX_PATH_MAX]; /* custom unix socket dir */
240 int pool_size; /* max server connections in one pool */
241 int res_pool_size; /* additional server connections in case of trouble */
243 const char *dbname; /* server-side name, pointer to inside startup_msg */
245 /* startup commands to send to server after connect. malloc-ed */
246 const char *connect_query;
248 usec_t inactive_time; /* when auto-database became inactive (to kill it after timeout) */
253 * A client or server connection.
255 * ->state corresponds to various lists the struct can be at.
257 struct PgSocket {
258 List head; /* list header */
259 PgSocket *link; /* the dest of packets */
260 PgPool *pool; /* parent pool, if NULL not yet assigned */
262 PgUser *auth_user; /* presented login, for client it may differ from pool->user */
264 SocketState state:8; /* this also specifies socket location */
266 bool ready:1; /* server: accepts new query */
267 bool close_needed:1; /* server: this socket must be closed ASAP */
268 bool setting_vars:1; /* server: setting client vars */
269 bool exec_on_connect:1; /* server: executing connect_query */
271 bool wait_for_welcome:1;/* client: no server yet in pool, cannot send welcome msg */
273 bool suspended:1; /* client/server: if the socket is suspended */
275 bool admin_user:1; /* console client: has admin rights */
276 bool own_user:1; /* console client: client with same uid on unix socket */
277 bool wait_for_response:1;/* console client: waits for completion of PAUSE/SUSPEND cmd */
279 usec_t connect_time; /* when connection was made */
280 usec_t request_time; /* last activity time */
281 usec_t query_start; /* query start moment */
283 uint8_t cancel_key[BACKENDKEY_LEN]; /* client: generated, server: remote */
284 PgAddr remote_addr; /* ip:port for remote endpoint */
285 PgAddr local_addr; /* ip:port for local endpoint */
287 VarCache vars; /* state of interesting server parameters */
289 SBuf sbuf; /* stream buffer, must be last */
292 #define RAW_IOBUF_SIZE offsetof(IOBuf, buf)
293 #define IOBUF_SIZE (RAW_IOBUF_SIZE + cf_sbuf_len)
295 /* where to store old fd info during SHOW FDS result processing */
296 #define tmp_sk_oldfd request_time
297 #define tmp_sk_linkfd query_start
298 /* takeover_clean_socket() needs to clean those up */
300 /* where the salt is temporarly stored */
301 #define tmp_login_salt cancel_key
303 /* main.c */
304 extern int cf_verbose;
305 extern int cf_daemon;
306 extern int cf_quiet;
308 extern char *cf_config_file;
309 extern char *cf_jobname;
310 extern int cf_syslog;
311 extern char *cf_syslog_facility;
313 extern char *cf_unix_socket_dir;
314 extern char *cf_listen_addr;
315 extern int cf_listen_port;
316 extern int cf_listen_backlog;
318 extern int cf_pool_mode;
319 extern int cf_max_client_conn;
320 extern int cf_default_pool_size;
321 extern int cf_res_pool_size;
322 extern usec_t cf_res_pool_timeout;
324 extern char * cf_autodb_connstr;
325 extern usec_t cf_autodb_idle_timeout;
327 extern usec_t cf_suspend_timeout;
328 extern usec_t cf_server_lifetime;
329 extern usec_t cf_server_idle_timeout;
330 extern char * cf_server_reset_query;
331 extern char * cf_server_check_query;
332 extern usec_t cf_server_check_delay;
333 extern usec_t cf_server_connect_timeout;
334 extern usec_t cf_server_login_retry;
335 extern usec_t cf_query_timeout;
336 extern usec_t cf_query_wait_timeout;
337 extern usec_t cf_client_idle_timeout;
338 extern usec_t cf_client_login_timeout;
339 extern int cf_server_round_robin;
341 extern int cf_auth_type;
342 extern char *cf_auth_file;
344 extern char *cf_logfile;
345 extern char *cf_pidfile;
347 extern char *cf_ignore_startup_params;
349 extern char *cf_admin_users;
350 extern char *cf_stats_users;
351 extern int cf_stats_period;
353 extern int cf_pause_mode;
354 extern int cf_shutdown;
355 extern int cf_reboot;
357 extern int cf_sbuf_loopcnt;
358 extern int cf_tcp_keepalive;
359 extern int cf_tcp_keepcnt;
360 extern int cf_tcp_keepidle;
361 extern int cf_tcp_keepintvl;
362 extern int cf_tcp_socket_buffer;
363 extern int cf_tcp_defer_accept;
365 extern int cf_log_connections;
366 extern int cf_log_disconnections;
367 extern int cf_log_pooler_errors;
369 extern ConfElem bouncer_params[];
371 extern usec_t g_suspend_start;
373 static inline PgSocket * _MUSTCHECK
374 pop_socket(StatList *slist)
376 List *item = statlist_pop(slist);
377 if (item == NULL)
378 return NULL;
379 return container_of(item, PgSocket, head);
382 static inline PgSocket *
383 first_socket(StatList *slist)
385 if (statlist_empty(slist))
386 return NULL;
387 return container_of(slist->head.next, PgSocket, head);
390 void load_config(bool reload);