2 * PgBouncer - Lightweight connection pooler for PostgreSQL.
4 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
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.
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.
28 #define FULLVER PACKAGE_NAME " version " PACKAGE_VERSION " (" DBGVER ")"
30 #define FULLVER PACKAGE_NAME " version " PACKAGE_VERSION
33 /* each state corresponts to a list */
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 */
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
;
93 /* to avoid allocations will use static buffers */
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 */
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
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
130 struct in_addr ip_addr
;
136 * Stats, kept per-pool.
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.
149 * ->stats is updated online.
150 * for each stats_period:
151 * ->older_stats = ->newer_stats
152 * ->newer_stats = ->stats
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 */
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.
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.
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.
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
304 extern int cf_verbose
;
305 extern int cf_daemon
;
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
);
379 return container_of(item
, PgSocket
, head
);
382 static inline PgSocket
*
383 first_socket(StatList
*slist
)
385 if (statlist_empty(slist
))
387 return container_of(slist
->head
.next
, PgSocket
, head
);
390 void load_config(bool reload
);