*** orig/postgresql-8.1.3/src/include/pgstat.h Wed Jan 18 19:35:16 2006 --- postgresql-8.1.3/src/include/pgstat.h Wed Apr 5 17:05:14 2006 *************** *** 280,286 **** typedef struct PgStat_StatDBEntry { Oid databaseid; - int destroy; int n_backends; PgStat_Counter n_xact_commit; PgStat_Counter n_xact_rollback; --- 280,285 ---- *************** *** 324,348 **** char activity[PGSTAT_ACTIVITY_SIZE]; } PgStat_StatBeEntry; - - /* ---------- - * PgStat_StatBeDead Because UDP packets can arrive out of - * order, we need to keep some information - * about backends that are known to be - * dead for some seconds. This info is held - * in a hash table of these structs. - * - * (This struct is not used in the stats file.) - * ---------- - */ - typedef struct PgStat_StatBeDead - { - int procpid; - int backendid; - int destroy; - } PgStat_StatBeDead; - - /* ---------- * PgStat_StatTabEntry The collector's data per table (or index) * ---------- --- 323,328 ---- *************** *** 350,356 **** typedef struct PgStat_StatTabEntry { Oid tableid; - int destroy; PgStat_Counter numscans; --- 330,335 ---- *** orig/postgresql-8.1.3/src/backend/postmaster/pgstat.c Wed Jan 18 19:35:16 2006 --- postgresql-8.1.3/src/backend/postmaster/pgstat.c Thu Apr 6 00:41:58 2006 *************** *** 69,80 **** #define PGSTAT_STAT_INTERVAL 500 /* How often to write the status file; * in milliseconds. */ - #define PGSTAT_DESTROY_DELAY 10000 /* How long to keep destroyed objects - * known, to give delayed UDP packets - * time to arrive; in milliseconds. */ - - #define PGSTAT_DESTROY_COUNT (PGSTAT_DESTROY_DELAY / PGSTAT_STAT_INTERVAL) - #define PGSTAT_RESTART_INTERVAL 60 /* How often to attempt to restart a * failed statistics collector; in * seconds. */ --- 69,74 ---- *************** *** 141,147 **** static TransactionId pgStatDBHashXact = InvalidTransactionId; static HTAB *pgStatDBHash = NULL; - static HTAB *pgStatBeDead = NULL; static PgStat_StatBeEntry *pgStatBeTable = NULL; static int pgStatNumBackends = 0; --- 135,140 ---- *************** *** 1552,1558 **** struct timeval timeout; struct timeval next_statwrite; bool need_statwrite; - HASHCTL hash_ctl; MyProcPid = getpid(); /* reset MyProcPid */ --- 1545,1550 ---- *************** *** 1610,1625 **** pgstat_read_statsfile(&pgStatDBHash, InvalidOid, NULL, NULL); /* - * Create the dead backend hashtable - */ - memset(&hash_ctl, 0, sizeof(hash_ctl)); - hash_ctl.keysize = sizeof(int); - hash_ctl.entrysize = sizeof(PgStat_StatBeDead); - hash_ctl.hash = tag_hash; - pgStatBeDead = hash_create("Dead Backends", PGSTAT_BE_HASH_SIZE, - &hash_ctl, HASH_ELEM | HASH_FUNCTION); - - /* * Create the known backends table */ pgStatBeTable = (PgStat_StatBeEntry *) --- 1602,1607 ---- *************** *** 2102,2108 **** pgstat_add_backend(PgStat_MsgHdr *msg) { PgStat_StatBeEntry *beentry; - PgStat_StatBeDead *deadbe; /* * Check that the backend ID is valid --- 2084,2089 ---- *************** *** 2129,2149 **** return 0; /* - * Lookup if this backend is known to be dead. This can be caused due to - * messages arriving in the wrong order - e.g. postmaster's BETERM message - * might have arrived before we received all the backends stats messages, - * or even a new backend with the same backendid was faster in sending his - * BESTART. - * - * If the backend is known to be dead, we ignore this add. - */ - deadbe = (PgStat_StatBeDead *) hash_search(pgStatBeDead, - (void *) &(msg->m_procpid), - HASH_FIND, NULL); - if (deadbe) - return 1; - - /* * Backend isn't known to be dead. If it's slot is currently used, we have * to kick out the old backend. */ --- 2110,2115 ---- *************** *** 2202,2208 **** result->n_xact_rollback = 0; result->n_blocks_fetched = 0; result->n_blocks_hit = 0; - result->destroy = 0; result->last_autovac_time = 0; memset(&hash_ctl, 0, sizeof(hash_ctl)); --- 2168,2173 ---- *************** *** 2228,2235 **** pgstat_sub_backend(int procpid) { int i; - PgStat_StatBeDead *deadbe; - bool found; /* * Search in the known-backends table for the slot containing this PID. --- 2193,2198 ---- *************** *** 2239,2265 **** if (pgStatBeTable[i].procpid == procpid) { /* - * That's him. Add an entry to the known to be dead backends. Due - * to possible misorder in the arrival of UDP packets it's - * possible that even if we know the backend is dead, there could - * still be messages queued that arrive later. Those messages must - * not cause our number of backends statistics to get screwed up, - * so we remember for a couple of seconds that this PID is dead - * and ignore them (only the counting of backends, not the table - * access stats they sent). - */ - deadbe = (PgStat_StatBeDead *) hash_search(pgStatBeDead, - (void *) &procpid, - HASH_ENTER, - &found); - - if (!found) - { - deadbe->backendid = i + 1; - deadbe->destroy = PGSTAT_DESTROY_COUNT; - } - - /* * Declare the backend slot empty. */ pgStatBeTable[i].procpid = 0; --- 2202,2207 ---- *************** *** 2287,2293 **** HASH_SEQ_STATUS tstat; PgStat_StatDBEntry *dbentry; PgStat_StatTabEntry *tabentry; - PgStat_StatBeDead *deadbe; FILE *fpout; int i; int32 format_id; --- 2229,2234 ---- *************** *** 2318,2348 **** while ((dbentry = (PgStat_StatDBEntry *) hash_seq_search(&hstat)) != NULL) { /* - * If this database is marked destroyed, count down and do so if it - * reaches 0. - */ - if (dbentry->destroy > 0) - { - if (--(dbentry->destroy) == 0) - { - if (dbentry->tables != NULL) - hash_destroy(dbentry->tables); - - if (hash_search(pgStatDBHash, - (void *) &(dbentry->databaseid), - HASH_REMOVE, NULL) == NULL) - ereport(ERROR, - (errmsg("database hash table corrupted " - "during cleanup --- abort"))); - } - - /* - * Don't include statistics for it. - */ - continue; - } - - /* * Write out the DB entry including the number of live backends. * We don't write the tables pointer since it's of no use to any * other process. --- 2259,2264 ---- *************** *** 2357,2382 **** while ((tabentry = (PgStat_StatTabEntry *) hash_seq_search(&tstat)) != NULL) { /* - * If table entry marked for destruction, same as above for the - * database entry. - */ - if (tabentry->destroy > 0) - { - if (--(tabentry->destroy) == 0) - { - if (hash_search(dbentry->tables, - (void *) &(tabentry->tableid), - HASH_REMOVE, NULL) == NULL) - ereport(ERROR, - (errmsg("tables hash table for " - "database %u corrupted during " - "cleanup --- abort", - dbentry->databaseid))); - } - continue; - } - - /* * At least we think this is still a live table. Emit its access * stats. */ --- 2273,2278 ---- *************** *** 2445,2470 **** PGSTAT_STAT_TMPFILE, PGSTAT_STAT_FILENAME))); unlink(PGSTAT_STAT_TMPFILE); } - - /* - * Clear out the dead backends table - */ - hash_seq_init(&hstat, pgStatBeDead); - while ((deadbe = (PgStat_StatBeDead *) hash_seq_search(&hstat)) != NULL) - { - /* - * Count down the destroy delay and remove entries where it reaches 0. - */ - if (--(deadbe->destroy) <= 0) - { - if (hash_search(pgStatBeDead, - (void *) &(deadbe->procpid), - HASH_REMOVE, NULL) == NULL) - ereport(ERROR, - (errmsg("dead-server-process hash table corrupted " - "during cleanup --- abort"))); - } - } } --- 2341,2346 ---- *************** *** 2598,2604 **** memcpy(dbentry, &dbbuf, sizeof(PgStat_StatDBEntry)); dbentry->tables = NULL; - dbentry->destroy = 0; dbentry->n_backends = 0; /* --- 2474,2479 ---- *************** *** 3001,3013 **** dbentry = pgstat_get_db_entry(msg->m_databaseid, true); - /* - * If the database is marked for destroy, this is a delayed UDP packet and - * not worth being counted. - */ - if (dbentry->destroy > 0) - return; - dbentry->n_xact_commit += (PgStat_Counter) (msg->m_xact_commit); dbentry->n_xact_rollback += (PgStat_Counter) (msg->m_xact_rollback); --- 2876,2881 ---- *************** *** 3040,3047 **** tabentry->blocks_fetched = tabmsg[i].t_blocks_fetched; tabentry->blocks_hit = tabmsg[i].t_blocks_hit; - - tabentry->destroy = 0; } else { --- 2908,2913 ---- *************** *** 3082,3088 **** pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len) { PgStat_StatDBEntry *dbentry; - PgStat_StatTabEntry *tabentry; int i; /* --- 2948,2953 ---- *************** *** 3100,3121 **** return; /* - * If the database is marked for destroy, this is a delayed UDP packet and - * the tables will go away at DB destruction. - */ - if (dbentry->destroy > 0) - return; - - /* * Process all table entries in the message. */ for (i = 0; i < msg->m_nentries; i++) { ! tabentry = (PgStat_StatTabEntry *) hash_search(dbentry->tables, ! (void *) &(msg->m_tableid[i]), ! HASH_FIND, NULL); ! if (tabentry) ! tabentry->destroy = PGSTAT_DESTROY_COUNT; } } --- 2965,2977 ---- return; /* * Process all table entries in the message. */ for (i = 0; i < msg->m_nentries; i++) { ! hash_search(dbentry->tables, ! (void *) &(msg->m_tableid[i]), ! HASH_REMOVE, NULL); } } *************** *** 3143,3152 **** dbentry = pgstat_get_db_entry(msg->m_databaseid, false); /* ! * Mark the database for destruction. */ ! if (dbentry) ! dbentry->destroy = PGSTAT_DESTROY_COUNT; } --- 2999,3014 ---- dbentry = pgstat_get_db_entry(msg->m_databaseid, false); /* ! * Remove the database */ ! if (dbentry) { ! if (dbentry->tables != NULL) ! hash_destroy(dbentry->tables); ! ! hash_search(pgStatDBHash, ! (void *) &(dbentry->databaseid), ! HASH_REMOVE, NULL); ! } } *************** *** 3188,3194 **** dbentry->n_xact_rollback = 0; dbentry->n_blocks_fetched = 0; dbentry->n_blocks_hit = 0; - dbentry->destroy = 0; memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); --- 3050,3055 ---- *************** *** 3199,3201 **** --- 3060,3063 ---- &hash_ctl, HASH_ELEM | HASH_FUNCTION); } + *** orig/postgresql-8.1.3/src/backend/postmaster/autovacuum.c Fri Jan 20 14:17:14 2006 --- postgresql-8.1.3/src/backend/postmaster/autovacuum.c Thu Apr 6 13:29:26 2006 *************** *** 367,382 **** continue; /* ! * Don't try to access a database that was dropped. This could only ! * happen if we read the pg_database flat file right before it was ! * modified, after the database was dropped from the pg_database ! * table. (This is of course a not-very-bulletproof test, but it's ! * cheap to make. If we do mistakenly choose a recently dropped ! * database, InitPostgres will fail and we'll drop out until the next ! * autovac run.) */ - if (tmp->entry->destroy != 0) - continue; /* * Else remember the db with oldest autovac time. --- 367,379 ---- continue; /* ! * We might try to access a database that was dropped. This could ! * only happen if we read the pg_database flat file right before it ! * was modified, after the database was dropped from the pg_database ! * table. If we do mistakenly choose a recently dropped database, ! * InitPostgres will fail and we'll drop out until the next autovac ! * run.) */ /* * Else remember the db with oldest autovac time.