database
Statistics are presented per database.
-total_requests
- Total number of SQL requests pooled by **pgbouncer**.
+total_xact_count
+ Total number of SQL transactions pooled by **pgbouncer**.
+
+total_query_count
+ Total number of SQL queries pooled by **pgbouncer**.
total_received
Total volume in bytes of network traffic received by **pgbouncer**.
total_sent
Total volume in bytes of network traffic sent by **pgbouncer**.
+total_xact_time
+ Total number of microseconds spent by **pgbouncer** when connected
+ to PostgreSQL in a transaction, either idle in transaction or
+ executing queries.
+
total_query_time
Total number of microseconds spent by **pgbouncer** when actively
- connected to PostgreSQL.
+ connected to PostgreSQL, executing queries.
-avg_req
- Average requests per second in last stat period.
+avg_xact_count
+ Average transactions per second in last stat period.
+
+avg_query_count
+ Average queries per second in last stat period.
avg_recv
Average received (from clients) bytes per second.
avg_sent
Average sent (to clients) bytes per second.
-avg_query
+avg_xact_time
+ Average transaction duration in microseconds.
+
+avg_query_time
Average query duration in microseconds.
SHOW SERVERS;
return handle_auth_response(client, pkt);
} else {
sbuf_prepare_send(sbuf, &client->sbuf, pkt->len);
- if (ready && client->query_start) {
+
+ /* every statement (independent or in a transaction) counts as a query */
+ if ((ready || idle_tx) && client->query_start) {
usec_t total;
total = get_cached_time() - client->query_start;
client->query_start = 0;
server->pool->stats.query_time += total;
slog_debug(client, "query time: %d us", (int)total);
- } else if (ready) {
+ } else if (ready || idle_tx) {
slog_warning(client, "FIXME: query end, but query_start == 0");
}
+
+ /* statement ending in "idle" ends a transaction */
+ if (ready && client->xact_start) {
+ usec_t total;
+ total = get_cached_time() - client->xact_start;
+ client->xact_start = 0;
+ server->pool->stats.xact_time += total;
+ slog_debug(client, "transaction time: %d us", (int)total);
+ } else if (ready) {
+ slog_warning(client, "FIXME: transaction end, but xact_start == 0");
+ }
}
} else {
if (server->state != SV_TESTED)
{
stat->server_bytes = 0;
stat->client_bytes = 0;
- stat->request_count = 0;
+ stat->query_count = 0;
stat->query_time = 0;
+ stat->xact_count = 0;
+ stat->xact_time = 0;
}
static void stat_add(PgStats *total, PgStats *stat)
{
total->server_bytes += stat->server_bytes;
total->client_bytes += stat->client_bytes;
- total->request_count += stat->request_count;
+ total->query_count += stat->query_count;
total->query_time += stat->query_time;
+ total->xact_count += stat->xact_count;
+ total->xact_time += stat->xact_time;
}
static void calc_average(PgStats *avg, PgStats *cur, PgStats *old)
{
- uint64_t qcount;
+ uint64_t query_count;
+ uint64_t xact_count;
+
usec_t dur = get_cached_time() - old_stamp;
reset_stats(avg);
if (dur <= 0)
return;
- avg->request_count = USEC * (cur->request_count - old->request_count) / dur;
+ query_count = cur->query_count - old->query_count;
+ xact_count = cur->xact_count - old->xact_count;
+
+ avg->query_count = USEC * query_count / dur;
+ avg->xact_count = USEC * xact_count / dur;
+
avg->client_bytes = USEC * (cur->client_bytes - old->client_bytes) / dur;
avg->server_bytes = USEC * (cur->server_bytes - old->server_bytes) / dur;
- qcount = cur->request_count - old->request_count;
- if (qcount > 0)
- avg->query_time = (cur->query_time - old->query_time) / qcount;
+
+ if (query_count > 0)
+ avg->query_time = (cur->query_time - old->query_time) / query_count;
+
+ if (xact_count > 0)
+ avg->xact_time = (cur->xact_time - old->xact_time) / xact_count;
}
static void write_stats(PktBuf *buf, PgStats *stat, PgStats *old, char *dbname)
{
PgStats avg;
calc_average(&avg, stat, old);
- pktbuf_write_DataRow(buf, "sqqqqqqqq", dbname,
- stat->request_count, stat->client_bytes,
- stat->server_bytes, stat->query_time,
- avg.request_count, avg.client_bytes,
- avg.server_bytes, avg.query_time);
+ pktbuf_write_DataRow(buf, "sqqqqqqqqqqqq", dbname,
+ stat->xact_count, stat->query_count,
+ stat->client_bytes, stat->server_bytes,
+ stat->xact_time, stat->query_time,
+ avg.xact_count, avg.query_count,
+ avg.client_bytes, avg.server_bytes,
+ avg.xact_time, avg.query_time);
}
bool admin_database_stats(PgSocket *client, struct StatList *pool_list)
return true;
}
- pktbuf_write_RowDescription(buf, "sqqqqqqqq", "database",
- "total_requests", "total_received",
- "total_sent", "total_query_time",
- "avg_req", "avg_recv", "avg_sent",
- "avg_query");
+ pktbuf_write_RowDescription(buf, "sqqqqqqqqqqqq", "database",
+ "total_xact_count", "total_query_count",
+ "total_received", "total_sent",
+ "total_xact_time", "total_query_time",
+ "avg_xact_count", "avg_query_count",
+ "avg_recv", "avg_sent",
+ "avg_xact_time", "avg_query_time");
statlist_for_each(item, pool_list) {
pool = container_of(item, PgPool, head);
#define WTOTAL(name) pktbuf_write_DataRow(buf, "sq", "total_" #name, st_total.name)
#define WAVG(name) pktbuf_write_DataRow(buf, "sq", "avg_" #name, avg.name)
- WTOTAL(request_count);
+ WTOTAL(xact_count);
+ WTOTAL(query_count);
WTOTAL(client_bytes);
WTOTAL(server_bytes);
+ WTOTAL(xact_time);
WTOTAL(query_time);
- WAVG(request_count);
+ WAVG(xact_count);
+ WAVG(query_count);
WAVG(client_bytes);
WAVG(server_bytes);
+ WAVG(xact_time);
WAVG(query_time);
admin_flush(client, buf, "SHOW");
}
calc_average(&avg, &cur_total, &old_total);
/* send totals to logfile */
- log_info("Stats: %" PRIu64 " req/s,"
+ log_info("Stats: %" PRIu64 " xacts/s,"
+ " %" PRIu64 " queries/s,"
" in %" PRIu64 " B/s,"
" out %" PRIu64 " B/s,"
+ " xact %" PRIu64 " us,"
" query %" PRIu64 " us",
- avg.request_count, avg.client_bytes,
- avg.server_bytes, avg.query_time);
+ avg.xact_count, avg.query_count,
+ avg.client_bytes, avg.server_bytes,
+ avg.xact_time, avg.query_time);
safe_evtimer_add(&ev_stats, &period);
}