diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index b549024010..fca054625b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2009, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.190 2009/08/12 20:53:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.191 2009/09/04 22:32:33 tgl Exp $ * ---------- */ #include "postgres.h" @@ -246,6 +246,8 @@ static void pgstat_beshutdown_hook(int code, Datum arg); static void pgstat_sighup_handler(SIGNAL_ARGS); static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create); +static PgStat_StatTabEntry *pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, + Oid tableoid, bool create); static void pgstat_write_statsfile(bool permanent); static HTAB *pgstat_read_statsfile(Oid onlydb, bool permanent); static void backend_read_statsfile(void); @@ -2940,6 +2942,52 @@ pgstat_get_db_entry(Oid databaseid, bool create) } +/* + * Lookup the hash table entry for the specified table. If no hash + * table entry exists, initialize it, if the create parameter is true. + * Else, return NULL. + */ +static PgStat_StatTabEntry * +pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, Oid tableoid, bool create) +{ + PgStat_StatTabEntry *result; + bool found; + HASHACTION action = (create ? HASH_ENTER : HASH_FIND); + + /* Lookup or create the hash table entry for this table */ + result = (PgStat_StatTabEntry *) hash_search(dbentry->tables, + &tableoid, + action, &found); + + if (!create && !found) + return NULL; + + /* If not found, initialize the new one. */ + if (!found) + { + result->numscans = 0; + result->tuples_returned = 0; + result->tuples_fetched = 0; + result->tuples_inserted = 0; + result->tuples_updated = 0; + result->tuples_deleted = 0; + result->tuples_hot_updated = 0; + result->n_live_tuples = 0; + result->n_dead_tuples = 0; + result->last_anl_tuples = 0; + result->blocks_fetched = 0; + result->blocks_hit = 0; + + result->vacuum_timestamp = 0; + result->autovac_vacuum_timestamp = 0; + result->analyze_timestamp = 0; + result->autovac_analyze_timestamp = 0; + } + + return result; +} + + /* ---------- * pgstat_write_statsfile() - * @@ -3553,10 +3601,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) tabentry->tuples_hot_updated = tabmsg[i].t_counts.t_tuples_hot_updated; tabentry->n_live_tuples = tabmsg[i].t_counts.t_new_live_tuples; tabentry->n_dead_tuples = tabmsg[i].t_counts.t_new_dead_tuples; + tabentry->last_anl_tuples = 0; tabentry->blocks_fetched = tabmsg[i].t_counts.t_blocks_fetched; tabentry->blocks_hit = tabmsg[i].t_counts.t_blocks_hit; - tabentry->last_anl_tuples = 0; tabentry->vacuum_timestamp = 0; tabentry->autovac_vacuum_timestamp = 0; tabentry->analyze_timestamp = 0; @@ -3734,19 +3782,10 @@ pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len) PgStat_StatDBEntry *dbentry; /* - * Lookup the database in the hashtable. Don't create the entry if it - * doesn't exist, because autovacuum may be processing a template - * database. If this isn't the case, the database is most likely to have - * an entry already. (If it doesn't, not much harm is done anyway -- - * it'll get created as soon as somebody actually uses the database.) + * Store the last autovacuum time in the database's hashtable entry. */ - dbentry = pgstat_get_db_entry(msg->m_databaseid, false); - if (dbentry == NULL) - return; + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); - /* - * Store the last autovacuum time in the database entry. - */ dbentry->last_autovac_time = msg->m_start_time; } @@ -3763,18 +3802,11 @@ pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len) PgStat_StatTabEntry *tabentry; /* - * Don't create either the database or table entry if it doesn't already - * exist. This avoids bloating the stats with entries for stuff that is - * only touched by vacuum and not by live operations. + * Store the data in the table's hashtable entry. */ - dbentry = pgstat_get_db_entry(msg->m_databaseid, false); - if (dbentry == NULL) - return; + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); - tabentry = hash_search(dbentry->tables, &(msg->m_tableoid), - HASH_FIND, NULL); - if (tabentry == NULL) - return; + tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); if (msg->m_autovacuum) tabentry->autovac_vacuum_timestamp = msg->m_vacuumtime; @@ -3821,18 +3853,11 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len) PgStat_StatTabEntry *tabentry; /* - * Don't create either the database or table entry if it doesn't already - * exist. This avoids bloating the stats with entries for stuff that is - * only touched by analyze and not by live operations. + * Store the data in the table's hashtable entry. */ - dbentry = pgstat_get_db_entry(msg->m_databaseid, false); - if (dbentry == NULL) - return; + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); - tabentry = hash_search(dbentry->tables, &(msg->m_tableoid), - HASH_FIND, NULL); - if (tabentry == NULL) - return; + tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); if (msg->m_autovacuum) tabentry->autovac_analyze_timestamp = msg->m_analyzetime;