5555 *
5656 *
5757 * IDENTIFICATION
58- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.80 2008/07/01 02:09:34 tgl Exp $
58+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.81 2008/07/17 21: 02:31 alvherre Exp $
5959 *
6060 *-------------------------------------------------------------------------
6161 */
@@ -176,6 +176,9 @@ typedef struct autovac_table
176176int at_vacuum_cost_delay ;
177177int at_vacuum_cost_limit ;
178178bool at_wraparound ;
179+ char * at_relname ;
180+ char * at_nspname ;
181+ char * at_datname ;
179182}autovac_table ;
180183
181184/*-------------
@@ -282,15 +285,13 @@ static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
282285PgStat_StatTabEntry * tabentry ,bool * dovacuum ,
283286bool * doanalyze ,bool * wraparound );
284287
285- static void autovacuum_do_vac_analyze (Oid relid ,bool dovacuum ,
286- bool doanalyze ,int freeze_min_age ,
287- bool for_wraparound ,
288+ static void autovacuum_do_vac_analyze (autovac_table * tab ,
288289BufferAccessStrategy bstrategy );
289290static HeapTuple get_pg_autovacuum_tuple_relid (Relation avRel ,Oid relid );
290291static PgStat_StatTabEntry * get_pgstat_tabentry_relid (Oid relid ,bool isshared ,
291292PgStat_StatDBEntry * shared ,
292293PgStat_StatDBEntry * dbentry );
293- static void autovac_report_activity (VacuumStmt * vacstmt , Oid relid );
294+ static void autovac_report_activity (autovac_table * tab );
294295static void avl_sighup_handler (SIGNAL_ARGS );
295296static void avl_sigusr1_handler (SIGNAL_ARGS );
296297static void avl_sigterm_handler (SIGNAL_ARGS );
@@ -2061,9 +2062,6 @@ do_autovacuum(void)
20612062autovac_table * tab ;
20622063WorkerInfo worker ;
20632064bool skipit ;
2064- char * datname ,
2065- * nspname ,
2066- * relname ;
20672065
20682066CHECK_FOR_INTERRUPTS ();
20692067
@@ -2158,13 +2156,17 @@ do_autovacuum(void)
21582156
21592157/*
21602158 * Save the relation name for a possible error message, to avoid a
2161- * catalog lookup in case of an error.Note: they must live in a
2162- * long-lived memory context because we call vacuum and analyze in
2163- * different transactions.
2159+ * catalog lookup in case of an error. If any of these return NULL,
2160+ * then the relation has been dropped since last we checked; skip it.
2161+ * Note: they must live in a long-lived memory context because we call
2162+ * vacuum and analyze in different transactions.
21642163 */
2165- datname = get_database_name (MyDatabaseId );
2166- nspname = get_namespace_name (get_rel_namespace (tab -> at_relid ));
2167- relname = get_rel_name (tab -> at_relid );
2164+
2165+ tab -> at_relname = get_rel_name (tab -> at_relid );
2166+ tab -> at_nspname = get_namespace_name (get_rel_namespace (tab -> at_relid ));
2167+ tab -> at_datname = get_database_name (MyDatabaseId );
2168+ if (!tab -> at_relname || !tab -> at_nspname || !tab -> at_datname )
2169+ gotodeleted ;
21682170
21692171/*
21702172 * We will abort vacuuming the current table if something errors out,
@@ -2175,12 +2177,7 @@ do_autovacuum(void)
21752177{
21762178/* have at it */
21772179MemoryContextSwitchTo (TopTransactionContext );
2178- autovacuum_do_vac_analyze (tab -> at_relid ,
2179- tab -> at_dovacuum ,
2180- tab -> at_doanalyze ,
2181- tab -> at_freeze_min_age ,
2182- tab -> at_wraparound ,
2183- bstrategy );
2180+ autovacuum_do_vac_analyze (tab ,bstrategy );
21842181
21852182/*
21862183 * Clear a possible query-cancel signal, to avoid a late reaction
@@ -2199,10 +2196,10 @@ do_autovacuum(void)
21992196HOLD_INTERRUPTS ();
22002197if (tab -> at_dovacuum )
22012198errcontext ("automatic vacuum of table \"%s.%s.%s\"" ,
2202- datname , nspname , relname );
2199+ tab -> at_datname , tab -> at_nspname , tab -> at_relname );
22032200else
22042201errcontext ("automatic analyze of table \"%s.%s.%s\"" ,
2205- datname , nspname , relname );
2202+ tab -> at_datname , tab -> at_nspname , tab -> at_relname );
22062203EmitErrorReport ();
22072204
22082205/* this resets the PGPROC flags too */
@@ -2219,10 +2216,14 @@ do_autovacuum(void)
22192216/* the PGPROC flags are reset at the next end of transaction */
22202217
22212218/* be tidy */
2219+ deleted :
2220+ if (tab -> at_datname != NULL )
2221+ pfree (tab -> at_datname );
2222+ if (tab -> at_nspname != NULL )
2223+ pfree (tab -> at_nspname );
2224+ if (tab -> at_relname != NULL )
2225+ pfree (tab -> at_relname );
22222226pfree (tab );
2223- pfree (datname );
2224- pfree (nspname );
2225- pfree (relname );
22262227
22272228/* remove my info from shared memory */
22282229LWLockAcquire (AutovacuumLock ,LW_EXCLUSIVE );
@@ -2299,6 +2300,8 @@ get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
22992300 * Recheck whether a plain table still needs vacuum or analyze; be it because
23002301 * it does directly, or because its TOAST table does. Return value is a valid
23012302 * autovac_table pointer if it does, NULL otherwise.
2303+ *
2304+ * Note that the returned autovac_table does not have the name fields set.
23022305 */
23032306static autovac_table *
23042307table_recheck_autovac (Oid relid )
@@ -2437,6 +2440,9 @@ table_recheck_autovac(Oid relid)
24372440tab -> at_vacuum_cost_limit = vac_cost_limit ;
24382441tab -> at_vacuum_cost_delay = vac_cost_delay ;
24392442tab -> at_wraparound = wraparound || toast_wraparound ;
2443+ tab -> at_relname = NULL ;
2444+ tab -> at_nspname = NULL ;
2445+ tab -> at_datname = NULL ;
24402446}
24412447
24422448heap_close (avRel ,AccessShareLock );
@@ -2607,8 +2613,7 @@ relation_needs_vacanalyze(Oid relid,
26072613 *Vacuum and/or analyze the specified table
26082614 */
26092615static void
2610- autovacuum_do_vac_analyze (Oid relid ,bool dovacuum ,bool doanalyze ,
2611- int freeze_min_age ,bool for_wraparound ,
2616+ autovacuum_do_vac_analyze (autovac_table * tab ,
26122617BufferAccessStrategy bstrategy )
26132618{
26142619VacuumStmt vacstmt ;
@@ -2617,18 +2622,18 @@ autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
26172622MemSet (& vacstmt ,0 ,sizeof (vacstmt ));
26182623
26192624vacstmt .type = T_VacuumStmt ;
2620- vacstmt .vacuum = dovacuum ;
2625+ vacstmt .vacuum = tab -> at_dovacuum ;
26212626vacstmt .full = false;
2622- vacstmt .analyze = doanalyze ;
2623- vacstmt .freeze_min_age = freeze_min_age ;
2627+ vacstmt .analyze = tab -> at_doanalyze ;
2628+ vacstmt .freeze_min_age = tab -> at_freeze_min_age ;
26242629vacstmt .verbose = false;
26252630vacstmt .relation = NULL ;/* not used since we pass a relid */
26262631vacstmt .va_cols = NIL ;
26272632
26282633/* Let pgstat know what we're doing */
2629- autovac_report_activity (& vacstmt , relid );
2634+ autovac_report_activity (tab );
26302635
2631- vacuum (& vacstmt ,relid ,bstrategy ,for_wraparound , true);
2636+ vacuum (& vacstmt ,tab -> at_relid ,bstrategy ,tab -> at_wraparound , true);
26322637}
26332638
26342639/*
@@ -2643,37 +2648,28 @@ autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
26432648 * bother to report "<IDLE>" or some such.
26442649 */
26452650static void
2646- autovac_report_activity (VacuumStmt * vacstmt , Oid relid )
2651+ autovac_report_activity (autovac_table * tab )
26472652{
2648- char * relname = get_rel_name (relid );
2649- char * nspname = get_namespace_name (get_rel_namespace (relid ));
2650-
26512653#define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
2652- char activity [MAX_AUTOVAC_ACTIV_LEN ];
2654+ char activity [MAX_AUTOVAC_ACTIV_LEN ];
2655+ int len ;
26532656
26542657/* Report the command and possible options */
2655- if (vacstmt -> vacuum )
2658+ if (tab -> at_dovacuum )
26562659snprintf (activity ,MAX_AUTOVAC_ACTIV_LEN ,
26572660"autovacuum: VACUUM%s" ,
2658- vacstmt -> analyze ?" ANALYZE" :"" );
2661+ tab -> at_doanalyze ?" ANALYZE" :"" );
26592662else
26602663snprintf (activity ,MAX_AUTOVAC_ACTIV_LEN ,
26612664"autovacuum: ANALYZE" );
26622665
26632666/*
26642667 * Report the qualified name of the relation.
2665- *
2666- * Paranoia is appropriate here in case relation was recently dropped ---
2667- * the lsyscache routines we just invoked will return NULL rather than
2668- * failing.
26692668 */
2670- if (relname && nspname )
2671- {
2672- int len = strlen (activity );
2669+ len = strlen (activity );
26732670
2674- snprintf (activity + len ,MAX_AUTOVAC_ACTIV_LEN - len ,
2675- " %s.%s" ,nspname ,relname );
2676- }
2671+ snprintf (activity + len ,MAX_AUTOVAC_ACTIV_LEN - len ,
2672+ " %s.%s" ,tab -> at_nspname ,tab -> at_relname );
26772673
26782674/* Set statement_timestamp() to current time for pg_stat_activity */
26792675SetCurrentStatementStartTimestamp ();