allowing the connection to be used by any clients. If the query raises errors,
they are logged but ignored otherwise.
+==== pool_mode ====
+
+Set the pool mode specific to this database. If not set,
+the default pool_mode is used.
+
=== Extra parameters ===
They allow setting default parameters on server connection.
pool_size::
Maximum number of server connections.
+pool_mode::
+ The pooling mode in user for this database.
+
==== SHOW FDS; ====
Internal command - shows list of fds in use with internal state attached to them.
#include "system.h"
+#include <usual/cfparser.h>
#include <usual/time.h>
#include <usual/list.h>
#include <usual/statlist.h>
#define POOL_SESSION 0
#define POOL_TX 1
#define POOL_STMT 2
+#define POOL_INHERIT 3
/* old style V2 header: len:4b code:4b */
#define OLD_HEADER_LEN 8
int pool_size; /* max server connections in one pool */
int res_pool_size; /* additional server connections in case of trouble */
+ int pool_mode; /* pool mode for this database */
const char *dbname; /* server-side name, pointer to inside startup_msg */
extern int cf_log_disconnections;
extern int cf_log_pooler_errors;
+extern const struct CfLookup pool_mode_map[];
+
extern usec_t g_suspend_start;
extern struct DNSContext *adns;
struct List *item;
const char *f_user;
PktBuf *buf;
+ struct CfValue cv;
+ int pool_mode;
buf = pktbuf_dynamic(256);
if (!buf) {
return true;
}
- pktbuf_write_RowDescription(buf, "ssissii",
+ pktbuf_write_RowDescription(buf, "ssissiis",
"name", "host", "port",
- "database", "force_user", "pool_size", "reserve_pool");
+ "database", "force_user", "pool_size", "reserve_pool",
+ "pool_mode");
statlist_for_each(item, &database_list) {
db = container_of(item, PgDatabase, head);
f_user = db->forced_user ? db->forced_user->name : NULL;
- pktbuf_write_DataRow(buf, "ssissii",
+ pool_mode = db->pool_mode;
+ if (pool_mode == POOL_INHERIT)
+ pool_mode = cf_pool_mode;
+ cv.value_p = &pool_mode;
+ cv.extra = pool_mode_map;
+ pktbuf_write_DataRow(buf, "ssissiis",
db->name, db->host, db->port,
db->dbname, f_user,
db->pool_size,
- db->res_pool_size);
+ db->res_pool_size,
+ cf_get_lookup(&cv));
}
admin_flush(admin, buf, "SHOW");
return true;
db->port = cf_listen_port;
db->pool_size = 2;
db->admin = 1;
+ db->pool_mode = POOL_STMT;
if (!force_user(db, "pgbouncer", ""))
fatal("no mem on startup - cannot alloc pgbouncer user");
char *p, *key, *val;
PktBuf *msg;
PgDatabase *db;
+ struct CfValue cv;
int pool_size = -1;
int res_pool_size = -1;
int dbname_ofs;
+ int pool_mode = POOL_INHERIT;
char *tmp_connstr;
const char *dbname = name;
int v_port;
+ cv.value_p = &pool_mode;
+ cv.extra = (const void *)pool_mode_map;
+
if (strcmp(name, "*") == 0) {
set_autodb(connstr);
return true;
pool_size = atoi(val);
else if (strcmp("reserve_pool", key) == 0)
res_pool_size = atoi(val);
- else if (strcmp("connect_query", key) == 0)
+ else if (strcmp("pool_mode", key) == 0) {
+ if (!cf_set_lookup(&cv, val)) {
+ log_error("skipping database %s because"
+ " of invalid pool mode: %s", name, val);
+ goto fail;
+ }
+ } else if (strcmp("connect_query", key) == 0)
connect_query = val;
else if (strcmp("application_name", key) == 0)
appname = val;
/* if pool_size < 0 it will be set later */
db->pool_size = pool_size;
db->res_pool_size = res_pool_size;
+ db->pool_mode = pool_mode;
if (db->host)
free(db->host);
{ NULL }
};
-static const struct CfLookup pool_mode_map[] = {
+const struct CfLookup pool_mode_map[] = {
{ "session", POOL_SESSION },
{ "transaction", POOL_TX },
{ "statement", POOL_STMT },
/* set ready only if no tx */
if (state == 'I') {
ready = true;
- } else if (cf_pool_mode == POOL_STMT) {
+ } else if (server->pool->db->pool_mode == POOL_STMT ||
+ (server->pool->db->pool_mode == POOL_INHERIT && cf_pool_mode == POOL_STMT)) {
disconnect_server(server, true, "Long transactions not allowed");
return false;
} else if (state == 'T' || state == 'E') {
PgSocket *server = container_of(sbuf, PgSocket, sbuf);
PgPool *pool = server->pool;
PktHdr pkt;
+ int pool_mode;
Assert(is_server_socket(server));
Assert(server->state != SV_FREE);
sbuf_continue(&client->sbuf);
break;
}
-
- if (cf_pool_mode != POOL_SESSION || server->state == SV_TESTED) {
+
+ pool_mode = server->pool->db->pool_mode;
+ if (pool_mode == POOL_INHERIT)
+ pool_mode = cf_pool_mode;
+ if (pool_mode != POOL_SESSION || server->state == SV_TESTED) {
switch (server->state) {
case SV_ACTIVE:
case SV_TESTED: