diff options
Diffstat (limited to 'machine/m_common.c')
-rw-r--r-- | machine/m_common.c | 85 |
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) |