Default: 20
+==== reserve_pool_size ====
+
+How many additional connections to allow to a pool.
+
+How many server connection to allow per user/database pair. Can be overrided in
+per-database config. 0 disables.
+
+Default: 0 (disabled)
+
+==== reserve_pool_timeout ====
+
+If a client has not been services in this many seconds, pgbouncer enables
+use of additional connections from reserve pool. 0 disables.
+
+Default: 5
+
==== server_round_robin ====
By default, pgbouncer reuses server connections in LIFO manner, so that few
; acceess to dest database will go with single user
forcedb = host=127.0.0.1 port=300 user=baz password=foo client_encoding=UNICODE datestyle=ISO connect_query='SELECT 1'
+nondefaultdb = pool_size=50 reserve_pool=10
+
;; Configuation section
[pgbouncer]
max_client_conn = 100
default_pool_size = 20
+; how many additional connection to allow in case of trouble
+;reserve_pool_size = 5
+
+; if a clients needs to wait more than this many seconds, use reserve pool
+;reserve_pool_timeout = 3
+
log_connections = 1
log_disconnections = 1
char unix_socket_dir[UNIX_PATH_MAX]; /* custom unix socket dir */
int pool_size; /* max server connections in one pool */
+ int res_pool_size; /* additional server connections in case of trouble */
const char *dbname; /* server-side name, pointer to inside startup_msg */
extern int cf_pool_mode;
extern int cf_max_client_conn;
extern int cf_default_pool_size;
+extern int cf_res_pool_size;
+extern usec_t cf_res_pool_timeout;
extern char * cf_autodb_connstr;
extern usec_t cf_autodb_idle_timeout;
return true;
}
- pktbuf_write_RowDescription(buf, "ssissi",
+ pktbuf_write_RowDescription(buf, "ssissii",
"name", "host", "port",
- "database", "force_user", "pool_size");
+ "database", "force_user", "pool_size", "reserve_pool");
statlist_for_each(item, &database_list) {
db = container_of(item, PgDatabase, head);
pktbuf_write_DataRow(buf, "ssissi",
db->name, host, db->addr.port,
db->dbname, f_user,
- db->pool_size);
+ db->pool_size,
+ db->res_pool_size);
}
admin_flush(admin, buf, "SHOW");
return true;
* statlist_count(&pool->new_server_list)
*/
- int many = cur - pool->db->pool_size;
+ int many = cur - (pool->db->pool_size + pool->db->res_pool_size);
Assert(pool->db->pool_size >= 0);
statlist_for_each_safe(item, &database_list, tmp) {
db = container_of(item, PgDatabase, head);
- if (db->db_dead)
+ if (db->db_dead) {
kill_database(db);
- else if (db->pool_size < 0)
+ continue;
+ }
+ if (db->pool_size < 0)
db->pool_size = cf_default_pool_size;
+ if (db->res_pool_size < 0)
+ db->res_pool_size = cf_res_pool_size;
}
}
PktBuf buf;
PgDatabase *db;
int pool_size = -1;
+ int res_pool_size = -1;
char *dbname = name;
char *host = NULL;
timezone = val;
else if (strcmp("pool_size", key) == 0)
pool_size = atoi(val);
+ else if (strcmp("reserve_pool", key) == 0)
+ res_pool_size = atoi(val);
else if (strcmp("connect_query", key) == 0)
connect_query = val;
else {
/* if pool_size < 0 it will be set later */
db->pool_size = pool_size;
+ db->res_pool_size = res_pool_size;
db->addr.port = v_port;
db->addr.ip_addr.s_addr = v_addr;
db->addr.is_unix = host ? 0 : 1;
int cf_max_client_conn = 100;
int cf_default_pool_size = 20;
+int cf_res_pool_size = 0;
+usec_t cf_res_pool_timeout = 5;
char *cf_server_reset_query = "";
char *cf_server_check_query = "select 1";
{"pool_mode", true, {get_mode, set_mode}},
{"max_client_conn", true, CF_INT, &cf_max_client_conn},
{"default_pool_size", true, CF_INT, &cf_default_pool_size},
+{"reserve_pool_size", true, CF_INT, &cf_res_pool_size},
+{"reserve_pool_timeout",true, CF_INT, &cf_res_pool_timeout},
{"syslog", true, CF_INT, &cf_syslog},
{"syslog_facility", true, CF_STR, &cf_syslog_facility},
#ifndef WIN32
/* do not forget to check pool_size like in config_postprocess */
if (db->pool_size < 0)
db->pool_size = cf_default_pool_size;
+ if (db->res_pool_size < 0)
+ db->res_pool_size = cf_res_pool_size;
}
return db;
/* is it allowed to add servers? */
total = pool_server_count(pool);
if (total >= pool->db->pool_size && pool->welcome_msg_ready) {
+ /* should we use reserve pool? */
+ if (cf_res_pool_timeout && pool->db->res_pool_size) {
+ usec_t now = get_cached_time();
+ PgSocket *c = first_socket(&pool->waiting_client_list);
+ if (c && (now - c->request_time) >= cf_res_pool_timeout) {
+ if (total < pool->db->pool_size + pool->db->res_pool_size) {
+ log_debug("reserve_pool activated");
+ goto allow_new;
+ }
+ }
+ }
log_debug("launch_new_connection: pool full (%d >= %d)",
total, pool->db->pool_size);
return;
}
+allow_new:
/* get free conn object */
server = obj_alloc(server_cache);
if (!server) {