summaryrefslogtreecommitdiffstats
path: root/machine/m_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'machine/m_common.c')
-rw-r--r--machine/m_common.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/machine/m_common.c b/machine/m_common.c
index fb9c6a6..fb7833a 100644
--- a/machine/m_common.c
+++ b/machine/m_common.c
@@ -13,6 +13,13 @@
#include "machine.h"
+/* Query to fetch information about database activity */
+#define QUERY_STAT_DB \
+ "SELECT datid, datname, numbackends, xact_commit, xact_rollback, \n" \
+ " blks_read, blks_hit, tup_returned, tup_fetched, \n" \
+ " tup_inserted, tup_updated, tup_deleted, conflicts \n" \
+ "FROM pg_stat_database;"
+
char *backendstatenames[] =
{
"", "idle", "active", "idltxn", "fast", "abort", "disabl", NULL
@@ -26,6 +33,84 @@ char *procstatenames[] =
char fmt_header_replication[] =
" PID USERNAME APPLICATION CLIENT STATE PRIMARY SENT WRITE FLUSH REPLAY SLAG WLAG FLAG RLAG";
+/*
+ * Get database info via the above QUERY_STAT_DB info.
+ * Returns rate info on the various statistics by comparing current
+ * values with previous values.
+ */
+void
+get_database_info(struct db_info *db_info, struct pg_conninfo_ctx *conninfo)
+{
+ struct timeval thistime;
+ double timediff;
+ int i;
+ int rows;
+ PGresult *pgresult = NULL;
+ struct db_info cur_info;
+ static struct timeval lasttime;
+ static struct db_info last_db_info;
+
+ /* calculate the time difference since our last check */
+ gettimeofday(&thistime, 0);
+ if (lasttime.tv_sec)
+ timediff = ((thistime.tv_sec - lasttime.tv_sec) +
+ (thistime.tv_usec - lasttime.tv_usec) * 1e-6);
+ else
+ timediff = 0;
+
+ lasttime = thistime;
+
+ rows = 0;
+ connect_to_db(conninfo);
+ if (conninfo->connection != NULL)
+ {
+ pgresult = PQexec(conninfo->connection, QUERY_STAT_DB);
+ if (PQresultStatus(pgresult) == PGRES_TUPLES_OK)
+ rows = PQntuples(pgresult);
+
+ }
+ if (rows == 0)
+ {
+ /* Database probably stopped, clear current and last */
+ memset(&last_db_info, 0, sizeof(last_db_info));
+ }
+ memset(&cur_info, 0, sizeof(cur_info));
+ for (i = 0; i < rows; i++)
+ {
+ PQgetvalue(pgresult, i, 2);
+ /* Count all databases, even with no active backends */
+ cur_info.numDb++;
+ cur_info.numXact += atoi(PQgetvalue(pgresult, i, 3));
+ cur_info.numRollback += atoi(PQgetvalue(pgresult, i, 4));
+ cur_info.numBlockRead += atoi(PQgetvalue(pgresult, i, 5));
+ cur_info.numBlockHit += atoi(PQgetvalue(pgresult, i, 6));
+ cur_info.numTupleFetched += atoi(PQgetvalue(pgresult, i, 8));
+ cur_info.numTupleAltered += atoi(PQgetvalue(pgresult, i, 9)) +
+ atoi(PQgetvalue(pgresult, i, 10)) +
+ atoi(PQgetvalue(pgresult, i, 11));
+ cur_info.numConflict += atoi(PQgetvalue(pgresult, i, 12));
+ }
+ if (pgresult != NULL)
+ PQclear(pgresult);
+ disconnect_from_db(conninfo);
+ if (timediff <= 0)
+ {
+ last_db_info = cur_info;
+ memset(db_info, 0, sizeof(*db_info));
+ return;
+ }
+
+ /* Compute the rate information */
+ db_info->numDb = cur_info.numDb;
+ db_info->numXact = (double)(cur_info.numXact - last_db_info.numXact) / timediff;
+ db_info->numRollback = (double)(cur_info.numRollback - last_db_info.numRollback) / timediff;
+ db_info->numBlockRead = (double)(cur_info.numBlockRead - last_db_info.numBlockRead) / timediff;
+ db_info->numBlockHit = (double)(cur_info.numBlockHit - last_db_info.numBlockHit) / timediff;
+ db_info->numTupleFetched = (double)(cur_info.numTupleFetched - last_db_info.numTupleFetched) / timediff;
+ db_info->numTupleAltered = (double)(cur_info.numTupleAltered - last_db_info.numTupleAltered) / timediff;
+ db_info->numConflict = (double)(cur_info.numConflict - last_db_info.numConflict) / timediff;
+ last_db_info = cur_info;
+}
void
update_state(int *pgstate, char *state)