*** 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.
