5555 *
5656 *
5757 * IDENTIFICATION
58- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.79 2008/06/05 15:47:32 alvherre Exp $
58+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.80 2008/07/01 02:09:34 tgl Exp $
5959 *
6060 *-------------------------------------------------------------------------
6161 */
7171#include "access/heapam.h"
7272#include "access/transam.h"
7373#include "access/xact.h"
74+ #include "catalog/dependency.h"
7475#include "catalog/indexing.h"
7576#include "catalog/namespace.h"
7677#include "catalog/pg_autovacuum.h"
9091#include "storage/pmsignal.h"
9192#include "storage/proc.h"
9293#include "storage/procarray.h"
93- #include "storage/sinval .h"
94+ #include "storage/sinvaladt .h"
9495#include "tcop/tcopprot.h"
9596#include "utils/flatfiles.h"
9697#include "utils/fmgroids.h"
@@ -275,10 +276,6 @@ static void autovac_balance_cost(void);
275276static void do_autovacuum (void );
276277static void FreeWorkerInfo (int code ,Datum arg );
277278
278- static void relation_check_autovac (Oid relid ,Form_pg_class classForm ,
279- Form_pg_autovacuum avForm ,PgStat_StatTabEntry * tabentry ,
280- List * * table_oids ,List * * table_toast_list ,
281- List * * toast_oids );
282279static autovac_table * table_recheck_autovac (Oid relid );
283280static void relation_needs_vacanalyze (Oid relid ,Form_pg_autovacuum avForm ,
284281Form_pg_class classForm ,
@@ -1912,19 +1909,16 @@ do_autovacuum(void)
19121909PgStat_StatTabEntry * tabentry ;
19131910HeapTuple avTup ;
19141911Oid relid ;
1912+ bool dovacuum ;
1913+ bool doanalyze ;
1914+ bool wraparound ;
1915+ int backendID ;
19151916
19161917/* Consider only regular and toast tables. */
19171918if (classForm -> relkind != RELKIND_RELATION &&
19181919classForm -> relkind != RELKIND_TOASTVALUE )
19191920continue ;
19201921
1921- /*
1922- * Skip temp tables (i.e. those in temp namespaces). We cannot safely
1923- * process other backends' temp tables.
1924- */
1925- if (isAnyTempNamespace (classForm -> relnamespace ))
1926- continue ;
1927-
19281922relid = HeapTupleGetOid (tuple );
19291923
19301924/* Fetch the pg_autovacuum tuple for the relation, if any */
@@ -1936,8 +1930,76 @@ do_autovacuum(void)
19361930tabentry = get_pgstat_tabentry_relid (relid ,classForm -> relisshared ,
19371931shared ,dbentry );
19381932
1939- relation_check_autovac (relid ,classForm ,avForm ,tabentry ,
1940- & table_oids ,& table_toast_list ,& toast_oids );
1933+ /* Check if it needs vacuum or analyze */
1934+ relation_needs_vacanalyze (relid ,avForm ,classForm ,tabentry ,
1935+ & dovacuum ,& doanalyze ,& wraparound );
1936+
1937+ /*
1938+ * Check if it is a temp table (presumably, of some other backend's).
1939+ * We cannot safely process other backends' temp tables.
1940+ */
1941+ backendID = GetTempNamespaceBackendId (classForm -> relnamespace );
1942+
1943+ if (backendID > 0 )
1944+ {
1945+ /* We just ignore it if the owning backend is still active */
1946+ if (backendID == MyBackendId || !BackendIdIsActive (backendID ))
1947+ {
1948+ /*
1949+ * We found an orphan temp table (which was probably left
1950+ * behind by a crashed backend). If it's so old as to need
1951+ * vacuum for wraparound, forcibly drop it. Otherwise just
1952+ * log a complaint.
1953+ */
1954+ if (wraparound && classForm -> relkind == RELKIND_RELATION )
1955+ {
1956+ ObjectAddress object ;
1957+
1958+ ereport (LOG ,
1959+ (errmsg ("autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"" ,
1960+ get_namespace_name (classForm -> relnamespace ),
1961+ NameStr (classForm -> relname ),
1962+ get_database_name (MyDatabaseId ))));
1963+ object .classId = RelationRelationId ;
1964+ object .objectId = relid ;
1965+ object .objectSubId = 0 ;
1966+ performDeletion (& object ,DROP_CASCADE );
1967+ }
1968+ else
1969+ {
1970+ ereport (LOG ,
1971+ (errmsg ("autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" ,
1972+ get_namespace_name (classForm -> relnamespace ),
1973+ NameStr (classForm -> relname ),
1974+ get_database_name (MyDatabaseId ))));
1975+ }
1976+ }
1977+ }
1978+ else if (classForm -> relkind == RELKIND_RELATION )
1979+ {
1980+ /* Plain relations that need work are added to table_oids */
1981+ if (dovacuum || doanalyze )
1982+ table_oids = lappend_oid (table_oids ,relid );
1983+ else if (OidIsValid (classForm -> reltoastrelid ))
1984+ {
1985+ /*
1986+ * If it doesn't appear to need vacuuming, but it has a toast
1987+ * table, remember the association to revisit below.
1988+ */
1989+ av_relation * rel = palloc (sizeof (av_relation ));
1990+
1991+ rel -> ar_relid = relid ;
1992+ rel -> ar_toastrelid = classForm -> reltoastrelid ;
1993+
1994+ table_toast_list = lappend (table_toast_list ,rel );
1995+ }
1996+ }
1997+ else
1998+ {
1999+ /* TOAST relations that need vacuum are added to toast_oids */
2000+ if (dovacuum )
2001+ toast_oids = lappend_oid (toast_oids ,relid );
2002+ }
19412003
19422004if (HeapTupleIsValid (avTup ))
19432005heap_freetuple (avTup );
@@ -2231,56 +2293,6 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
22312293return tabentry ;
22322294}
22332295
2234- /*
2235- * relation_check_autovac
2236- *
2237- * For a given relation (either a plain table or TOAST table), check whether it
2238- * needs vacuum or analyze.
2239- *
2240- * Plain tables that need either are added to the table_list. TOAST tables
2241- * that need vacuum are added to toast_list. Plain tables that don't need
2242- * either but which have a TOAST table are added, as a struct, to
2243- * table_toast_list. The latter is to allow appending the OIDs of the plain
2244- * tables whose TOAST table needs vacuuming into the plain tables list, which
2245- * allows us to substantially reduce the number of "rechecks" that we need to
2246- * do later on.
2247- */
2248- static void
2249- relation_check_autovac (Oid relid ,Form_pg_class classForm ,
2250- Form_pg_autovacuum avForm ,PgStat_StatTabEntry * tabentry ,
2251- List * * table_oids ,List * * table_toast_list ,
2252- List * * toast_oids )
2253- {
2254- bool dovacuum ;
2255- bool doanalyze ;
2256- bool dummy ;
2257-
2258- relation_needs_vacanalyze (relid ,avForm ,classForm ,tabentry ,
2259- & dovacuum ,& doanalyze ,& dummy );
2260-
2261- if (classForm -> relkind == RELKIND_TOASTVALUE )
2262- {
2263- if (dovacuum )
2264- * toast_oids = lappend_oid (* toast_oids ,relid );
2265- }
2266- else
2267- {
2268- Assert (classForm -> relkind == RELKIND_RELATION );
2269-
2270- if (dovacuum || doanalyze )
2271- * table_oids = lappend_oid (* table_oids ,relid );
2272- else if (OidIsValid (classForm -> reltoastrelid ))
2273- {
2274- av_relation * rel = palloc (sizeof (av_relation ));
2275-
2276- rel -> ar_relid = relid ;
2277- rel -> ar_toastrelid = classForm -> reltoastrelid ;
2278-
2279- * table_toast_list = lappend (* table_toast_list ,rel );
2280- }
2281- }
2282- }
2283-
22842296/*
22852297 * table_recheck_autovac
22862298 *