]> granicus.if.org Git - pgbouncer/blob - include/bouncer.h
New tunable 'sbuf_loopcnt' to limit time spent on one socket.
[pgbouncer] / include / bouncer.h
1 /*
2  * PgBouncer - Lightweight connection pooler for PostgreSQL.
3  * 
4  * Copyright (c) 2007 Marko Kreen, Skype Technologies OÜ
5  * 
6  * Permission to use, copy, modify, and 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.
17  */
18
19 /*
20  * core structures
21  */
22
23 #include "system.h"
24
25 #include <event.h>
26
27 #ifdef DBGVER
28 #define FULLVER   PACKAGE_NAME " version " PACKAGE_VERSION " (" DBGVER ")"
29 #else
30 #define FULLVER   PACKAGE_NAME " version " PACKAGE_VERSION
31 #endif
32
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 */
41
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 */
49 };
50
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 */
55 };
56
57 #define is_server_socket(sk) ((sk)->state >= SV_FREE)
58
59
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;
68
69 #include "aatree.h"
70 #include "hash.h"
71 #include "util.h"
72 #include "list.h"
73 #include "mbuf.h"
74 #include "iobuf.h"
75 #include "sbuf.h"
76 #include "pktbuf.h"
77 #include "varcache.h"
78 #include "slab.h"
79
80 #include "admin.h"
81 #include "loader.h"
82 #include "client.h"
83 #include "server.h"
84 #include "pooler.h"
85 #include "proto.h"
86 #include "objects.h"
87 #include "stats.h"
88 #include "takeover.h"
89 #include "janitor.h"
90
91 /* to avoid allocations will use static buffers */
92 #define MAX_DBNAME      64
93 #define MAX_USERNAME    64
94 #define MAX_PASSWORD    64
95
96 /* auth modes, should match PG's */
97 #define AUTH_ANY        -1 /* same as trust but without username check */
98 #define AUTH_TRUST      0
99 #define AUTH_PLAIN      3
100 #define AUTH_CRYPT      4
101 #define AUTH_MD5        5
102 #define AUTH_CREDS      6
103
104 /* type codes for weird pkts */
105 #define PKT_STARTUP     0x30000
106 #define PKT_CANCEL      80877102
107 #define PKT_SSLREQ      80877103
108
109 #define POOL_SESSION    0
110 #define POOL_TX         1
111 #define POOL_STMT       2
112
113 /* old style V2 header: len:4b code:4b */
114 #define OLD_HEADER_LEN  8
115 /* new style V3 packet header len - type:1b, len:4b */ 
116 #define NEW_HEADER_LEN  5
117
118 #define BACKENDKEY_LEN  8
119
120 /*
121  * Remote/local address
122  */
123 struct PgAddr {
124         struct in_addr ip_addr;
125         unsigned short port;
126         bool is_unix;
127 };
128
129 /*
130  * Stats, kept per-pool.
131  */
132 struct PgStats {
133         uint64_t request_count;
134         uint64_t server_bytes;
135         uint64_t client_bytes;
136         usec_t query_time;      /* total req time in us */
137 };
138
139 /*
140  * Contains connections for one db+user pair.
141  *
142  * Stats:
143  *   ->stats is updated online.
144  *   for each stats_period:
145  *   ->older_stats = ->newer_stats
146  *   ->newer_stats = ->stats
147  */
148 struct PgPool {
149         List head;                      /* entry in global pool_list */
150         List map_head;                  /* entry in user->pool_list */
151
152         PgDatabase *db;                 /* corresponging database */
153         PgUser *user;                   /* user logged in as */
154
155         StatList active_client_list;    /* waiting events logged in clients */
156         StatList waiting_client_list;   /* client waits for a server to be available */
157         StatList cancel_req_list;       /* closed client connections with server key */
158
159         StatList active_server_list;    /* servers linked with clients */
160         StatList idle_server_list;      /* servers ready to be linked with clients */
161         StatList used_server_list;      /* server just unlinked from clients */
162         StatList tested_server_list;    /* server in testing process */
163         StatList new_server_list;       /* servers in login phase */
164
165         PgStats stats;
166         PgStats newer_stats;
167         PgStats older_stats;
168
169         /* database info to be sent to client */
170         uint8_t welcome_msg[256];       /* ServerParams without VarCache ones */
171         unsigned welcome_msg_len;
172
173         VarCache orig_vars;             /* default params from server */
174
175         usec_t last_lifetime_disconnect;/* last time when server_lifetime was applied */
176
177         /* if last connect failed, there should be delay before next */
178         usec_t last_connect_time;
179         unsigned last_connect_failed:1;
180
181         unsigned welcome_msg_ready:1;
182 };
183
184 #define pool_server_count(pool) ( \
185                 statlist_count(&(pool)->active_server_list) + \
186                 statlist_count(&(pool)->idle_server_list) + \
187                 statlist_count(&(pool)->new_server_list) + \
188                 statlist_count(&(pool)->tested_server_list) + \
189                 statlist_count(&(pool)->used_server_list))
190
191 #define pool_client_count(pool) ( \
192                 statlist_count(&(pool)->active_client_list) + \
193                 statlist_count(&(pool)->waiting_client_list))
194
195 /*
196  * A user in login db.
197  *
198  * fixme: remove ->head as ->tree_node should be enough.
199  *
200  * For databases where remote user is forced, the pool is:
201  * first(db->forced_user->pool_list), where pool_list has only one entry.
202  *
203  * Otherwise, ->pool_list contains multiple pools, for all PgDatabases
204  * whis user has logged in.
205  */
206 struct PgUser {
207         List head;              /* used to attach user to list */
208         List pool_list;         /* list of pools where pool->user == this user */
209         Node tree_node;         /* used to attach user to tree */
210         char name[MAX_USERNAME];
211         char passwd[MAX_PASSWORD];
212 };
213
214 /*
215  * A database entry from config.
216  */
217 struct PgDatabase {
218         List head;
219         char name[MAX_DBNAME];  /* db name for clients */
220
221         bool db_paused;         /* PAUSE <db>; was issued */
222         bool db_dead;           /* used on RELOAD/SIGHUP to later detect removed dbs */
223         bool admin;             /* internal console db */
224
225         uint8_t startup_params[256]; /* partial StartupMessage (without user) be sent to server */
226         unsigned startup_params_len;
227
228         PgUser *forced_user;    /* if not NULL, the user/psw is forced */
229
230         PgAddr addr;            /* address prepared for connect() */
231         char unix_socket_dir[UNIX_PATH_MAX]; /* custom unix socket dir */
232
233         int pool_size;          /* max server connections in one pool */
234
235         const char *dbname;     /* server-side name, pointer to inside startup_msg */
236
237         /* startup commands to send to server after connect. malloc-ed */
238         const char *connect_query;
239 };
240
241
242 /*
243  * A client or server connection.
244  *
245  * ->state corresponds to various lists the struct can be at.
246  */
247 struct PgSocket {
248         List head;              /* list header */
249         PgSocket *link;         /* the dest of packets */
250         PgPool *pool;           /* parent pool, if NULL not yet assigned */
251
252         PgUser *auth_user;      /* presented login, for client it may differ from pool->user */
253
254         SocketState state:8;    /* this also specifies socket location */
255
256         bool ready:1;           /* server: accepts new query */
257         bool close_needed:1;    /* server: this socket must be closed ASAP */
258         bool setting_vars:1;    /* server: setting client vars */
259         bool exec_on_connect:1; /* server: executing connect_query */
260
261         bool wait_for_welcome:1;/* client: no server yet in pool, cannot send welcome msg */
262
263         bool suspended:1;       /* client/server: if the socket is suspended */
264
265         bool admin_user:1;      /* console client: has admin rights */
266         bool own_user:1;        /* console client: client with same uid on unix socket */
267         bool wait_for_response:1;/* console client: waits for completion of PAUSE/SUSPEND cmd */
268
269         usec_t connect_time;    /* when connection was made */
270         usec_t request_time;    /* last activity time */
271         usec_t query_start;     /* query start moment */
272
273         uint8_t cancel_key[BACKENDKEY_LEN]; /* client: generated, server: remote */
274         PgAddr remote_addr;     /* ip:port for remote endpoint */
275         PgAddr local_addr;      /* ip:port for local endpoint */
276
277         VarCache vars;          /* state of interesting server parameters */
278
279         SBuf sbuf;              /* stream buffer, must be last */
280 };
281
282 #define RAW_IOBUF_SIZE  offsetof(IOBuf, buf)
283 #define IOBUF_SIZE      (RAW_IOBUF_SIZE + cf_sbuf_len)
284
285 /* where to store old fd info during SHOW FDS result processing */
286 #define tmp_sk_oldfd    request_time
287 #define tmp_sk_linkfd   query_start
288 /* takeover_clean_socket() needs to clean those up */
289
290 /* where the salt is temporarly stored */
291 #define tmp_login_salt  cancel_key
292
293 /* main.c */
294 extern int cf_verbose;
295 extern int cf_daemon;
296 extern int cf_quiet;
297
298 extern char *cf_jobname;
299 extern int cf_syslog;
300 extern char *cf_syslog_facility;
301
302 extern char *cf_unix_socket_dir;
303 extern char *cf_listen_addr;
304 extern int cf_listen_port;
305
306 extern int cf_pool_mode;
307 extern int cf_max_client_conn;
308 extern int cf_default_pool_size;
309
310 extern usec_t cf_suspend_timeout;
311 extern usec_t cf_server_lifetime;
312 extern usec_t cf_server_idle_timeout;
313 extern char * cf_server_reset_query;
314 extern char * cf_server_check_query;
315 extern usec_t cf_server_check_delay;
316 extern usec_t cf_server_connect_timeout;
317 extern usec_t cf_server_login_retry;
318 extern usec_t cf_query_timeout;
319 extern usec_t cf_client_idle_timeout;
320 extern usec_t cf_client_login_timeout;
321 extern int cf_server_round_robin;
322
323 extern int cf_auth_type;
324 extern char *cf_auth_file;
325
326 extern char *cf_logfile;
327 extern char *cf_pidfile;
328
329 extern char *cf_ignore_startup_params;
330
331 extern char *cf_admin_users;
332 extern char *cf_stats_users;
333 extern int cf_stats_period;
334
335 extern int cf_pause_mode;
336 extern int cf_shutdown;
337 extern int cf_reboot;
338
339 extern int cf_sbuf_loopcnt;
340 extern int cf_sbuf_len;
341 extern int cf_tcp_keepalive;
342 extern int cf_tcp_keepcnt;
343 extern int cf_tcp_keepidle;
344 extern int cf_tcp_keepintvl;
345 extern int cf_tcp_socket_buffer;
346 extern int cf_tcp_defer_accept;
347
348 extern int cf_log_connections;
349 extern int cf_log_disconnections;
350 extern int cf_log_pooler_errors;
351
352 extern ConfElem bouncer_params[];
353
354 extern usec_t g_suspend_start;
355
356 static inline PgSocket * _MUSTCHECK
357 pop_socket(StatList *slist)
358 {
359         List *item = statlist_pop(slist);
360         if (item == NULL)
361                 return NULL;
362         return container_of(item, PgSocket, head);
363 }
364
365 static inline PgSocket *
366 first_socket(StatList *slist)
367 {
368         if (statlist_empty(slist))
369                 return NULL;
370         return container_of(slist->head.next, PgSocket, head);
371 }
372
373 void load_config(bool reload);
374
375