55
55
*
56
56
*
57
57
* 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 $
59
59
*
60
60
*-------------------------------------------------------------------------
61
61
*/
71
71
#include "access/heapam.h"
72
72
#include "access/transam.h"
73
73
#include "access/xact.h"
74
+ #include "catalog/dependency.h"
74
75
#include "catalog/indexing.h"
75
76
#include "catalog/namespace.h"
76
77
#include "catalog/pg_autovacuum.h"
90
91
#include "storage/pmsignal.h"
91
92
#include "storage/proc.h"
92
93
#include "storage/procarray.h"
93
- #include "storage/sinval .h"
94
+ #include "storage/sinvaladt .h"
94
95
#include "tcop/tcopprot.h"
95
96
#include "utils/flatfiles.h"
96
97
#include "utils/fmgroids.h"
@@ -275,10 +276,6 @@ static void autovac_balance_cost(void);
275
276
static void do_autovacuum (void );
276
277
static void FreeWorkerInfo (int code , Datum arg );
277
278
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 );
282
279
static autovac_table * table_recheck_autovac (Oid relid );
283
280
static void relation_needs_vacanalyze (Oid relid , Form_pg_autovacuum avForm ,
284
281
Form_pg_class classForm ,
@@ -1912,19 +1909,16 @@ do_autovacuum(void)
1912
1909
PgStat_StatTabEntry * tabentry ;
1913
1910
HeapTuple avTup ;
1914
1911
Oid relid ;
1912
+ bool dovacuum ;
1913
+ bool doanalyze ;
1914
+ bool wraparound ;
1915
+ int backendID ;
1915
1916
1916
1917
/* Consider only regular and toast tables. */
1917
1918
if (classForm -> relkind != RELKIND_RELATION &&
1918
1919
classForm -> relkind != RELKIND_TOASTVALUE )
1919
1920
continue ;
1920
1921
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
-
1928
1922
relid = HeapTupleGetOid (tuple );
1929
1923
1930
1924
/* Fetch the pg_autovacuum tuple for the relation, if any */
@@ -1936,8 +1930,76 @@ do_autovacuum(void)
1936
1930
tabentry = get_pgstat_tabentry_relid (relid , classForm -> relisshared ,
1937
1931
shared , dbentry );
1938
1932
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
+ }
1941
2003
1942
2004
if (HeapTupleIsValid (avTup ))
1943
2005
heap_freetuple (avTup );
@@ -2231,56 +2293,6 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
2231
2293
return tabentry ;
2232
2294
}
2233
2295
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
-
2284
2296
/*
2285
2297
* table_recheck_autovac
2286
2298
*
0 commit comments