Alvaro Herrera wrote:
> Anyway, I propose this patch in HEAD to close this hole. For 8.3 I'm
> thinking in just rearranging the get_*_name calls and adding the goto.
> Thoughts?
Sorry, really attached.
--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.80
diff -c -p -r1.80 autovacuum.c
*** src/backend/postmaster/autovacuum.c 1 Jul 2008 02:09:34 -0000 1.80
--- src/backend/postmaster/autovacuum.c 17 Jul 2008 15:42:00 -0000
*************** typedef struct autovac_table
*** 176,181 ****
--- 176,184 ----
int at_vacuum_cost_delay;
int at_vacuum_cost_limit;
bool at_wraparound;
+ char *at_relname;
+ char *at_nspname;
+ char *at_datname;
} autovac_table;
/*-------------
*************** static void relation_needs_vacanalyze(Oi
*** 282,296 ****
PgStat_StatTabEntry *tabentry, bool *dovacuum,
bool *doanalyze, bool *wraparound);
! static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum,
! bool doanalyze, int freeze_min_age,
! bool for_wraparound,
BufferAccessStrategy bstrategy);
static HeapTuple get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid);
static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
PgStat_StatDBEntry *shared,
PgStat_StatDBEntry *dbentry);
! static void autovac_report_activity(VacuumStmt *vacstmt, Oid relid);
static void avl_sighup_handler(SIGNAL_ARGS);
static void avl_sigusr1_handler(SIGNAL_ARGS);
static void avl_sigterm_handler(SIGNAL_ARGS);
--- 285,297 ----
PgStat_StatTabEntry *tabentry, bool *dovacuum,
bool *doanalyze, bool *wraparound);
! static void autovacuum_do_vac_analyze(autovac_table *tab,
BufferAccessStrategy bstrategy);
static HeapTuple get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid);
static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
PgStat_StatDBEntry *shared,
PgStat_StatDBEntry *dbentry);
! static void autovac_report_activity(autovac_table *tab);
static void avl_sighup_handler(SIGNAL_ARGS);
static void avl_sigusr1_handler(SIGNAL_ARGS);
static void avl_sigterm_handler(SIGNAL_ARGS);
*************** do_autovacuum(void)
*** 2061,2069 ****
autovac_table *tab;
WorkerInfo worker;
bool skipit;
- char *datname,
- *nspname,
- *relname;
CHECK_FOR_INTERRUPTS();
--- 2062,2067 ----
*************** do_autovacuum(void)
*** 2158,2170 ****
/*
* Save the relation name for a possible error message, to avoid a
! * catalog lookup in case of an error. Note: they must live in a
! * long-lived memory context because we call vacuum and analyze in
! * different transactions.
! */
! datname = get_database_name(MyDatabaseId);
! nspname = get_namespace_name(get_rel_namespace(tab->at_relid));
! relname = get_rel_name(tab->at_relid);
/*
* We will abort vacuuming the current table if something errors out,
--- 2156,2171 ----
/*
* Save the relation name for a possible error message, to avoid a
! * catalog lookup in case of an error. If get_rel_name returns NULL,
! * then the relation has been dropped since last we checked. Note:
! * they must live in a long-lived memory context because we call vacuum
! * and analyze in different transactions.
! */
! tab->at_relname = get_rel_name(tab->at_relid);
! if (tab->at_relname == NULL)
! goto table_deleted;
! tab->at_datname = get_database_name(MyDatabaseId);
! tab->at_nspname = get_namespace_name(get_rel_namespace(tab->at_relid));
/*
* We will abort vacuuming the current table if something errors out,
*************** do_autovacuum(void)
*** 2175,2186 ****
{
/* have at it */
MemoryContextSwitchTo(TopTransactionContext);
! autovacuum_do_vac_analyze(tab->at_relid,
! tab->at_dovacuum,
! tab->at_doanalyze,
! tab->at_freeze_min_age,
! tab->at_wraparound,
! bstrategy);
/*
* Clear a possible query-cancel signal, to avoid a late reaction
--- 2176,2182 ----
{
/* have at it */
MemoryContextSwitchTo(TopTransactionContext);
! autovacuum_do_vac_analyze(tab, bstrategy);
/*
* Clear a possible query-cancel signal, to avoid a late reaction
*************** do_autovacuum(void)
*** 2199,2208 ****
HOLD_INTERRUPTS();
if (tab->at_dovacuum)
errcontext("automatic vacuum of table \"%s.%s.%s\"",
! datname, nspname, relname);
else
errcontext("automatic analyze of table \"%s.%s.%s\"",
! datname, nspname, relname);
EmitErrorReport();
/* this resets the PGPROC flags too */
--- 2195,2204 ----
HOLD_INTERRUPTS();
if (tab->at_dovacuum)
errcontext("automatic vacuum of table \"%s.%s.%s\"",
! tab->at_datname, tab->at_nspname, tab->at_relname);
else
errcontext("automatic analyze of table \"%s.%s.%s\"",
! tab->at_datname, tab->at_nspname, tab->at_relname);
EmitErrorReport();
/* this resets the PGPROC flags too */
*************** do_autovacuum(void)
*** 2219,2228 ****
/* the PGPROC flags are reset at the next end of transaction */
/* be tidy */
pfree(tab);
- pfree(datname);
- pfree(nspname);
- pfree(relname);
/* remove my info from shared memory */
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
--- 2215,2226 ----
/* the PGPROC flags are reset at the next end of transaction */
/* be tidy */
+ pfree(tab->at_datname);
+ pfree(tab->at_nspname);
+ pfree(tab->at_relname);
+
+ table_deleted:
pfree(tab);
/* remove my info from shared memory */
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
*************** get_pgstat_tabentry_relid(Oid relid, boo
*** 2299,2304 ****
--- 2297,2304 ----
* Recheck whether a plain table still needs vacuum or analyze; be it because
* it does directly, or because its TOAST table does. Return value is a valid
* autovac_table pointer if it does, NULL otherwise.
+ *
+ * Note that the returned autovac_table does not have the name fields set.
*/
static autovac_table *
table_recheck_autovac(Oid relid)
*************** table_recheck_autovac(Oid relid)
*** 2437,2442 ****
--- 2437,2445 ----
tab->at_vacuum_cost_limit = vac_cost_limit;
tab->at_vacuum_cost_delay = vac_cost_delay;
tab->at_wraparound = wraparound || toast_wraparound;
+ tab->at_relname = NULL;
+ tab->at_nspname = NULL;
+ tab->at_datname = NULL;
}
heap_close(avRel, AccessShareLock);
*************** relation_needs_vacanalyze(Oid relid,
*** 2607,2614 ****
* Vacuum and/or analyze the specified table
*/
static void
! autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
! int freeze_min_age, bool for_wraparound,
BufferAccessStrategy bstrategy)
{
VacuumStmt vacstmt;
--- 2610,2616 ----
* Vacuum and/or analyze the specified table
*/
static void
! autovacuum_do_vac_analyze(autovac_table *tab,
BufferAccessStrategy bstrategy)
{
VacuumStmt vacstmt;
*************** autovacuum_do_vac_analyze(Oid relid, boo
*** 2617,2634 ****
MemSet(&vacstmt, 0, sizeof(vacstmt));
vacstmt.type = T_VacuumStmt;
! vacstmt.vacuum = dovacuum;
vacstmt.full = false;
! vacstmt.analyze = doanalyze;
! vacstmt.freeze_min_age = freeze_min_age;
vacstmt.verbose = false;
vacstmt.relation = NULL; /* not used since we pass a relid */
vacstmt.va_cols = NIL;
/* Let pgstat know what we're doing */
! autovac_report_activity(&vacstmt, relid);
! vacuum(&vacstmt, relid, bstrategy, for_wraparound, true);
}
/*
--- 2619,2636 ----
MemSet(&vacstmt, 0, sizeof(vacstmt));
vacstmt.type = T_VacuumStmt;
! vacstmt.vacuum = tab->at_dovacuum;
vacstmt.full = false;
! vacstmt.analyze = tab->at_doanalyze;
! vacstmt.freeze_min_age = tab->at_freeze_min_age;
vacstmt.verbose = false;
vacstmt.relation = NULL; /* not used since we pass a relid */
vacstmt.va_cols = NIL;
/* Let pgstat know what we're doing */
! autovac_report_activity(tab);
! vacuum(&vacstmt, tab->at_relid, bstrategy, tab->at_wraparound, true);
}
/*
*************** autovacuum_do_vac_analyze(Oid relid, boo
*** 2643,2679 ****
* bother to report "<IDLE>" or some such.
*/
static void
! autovac_report_activity(VacuumStmt *vacstmt, Oid relid)
{
- char *relname = get_rel_name(relid);
- char *nspname = get_namespace_name(get_rel_namespace(relid));
-
#define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
! char activity[MAX_AUTOVAC_ACTIV_LEN];
/* Report the command and possible options */
! if (vacstmt->vacuum)
snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
"autovacuum: VACUUM%s",
! vacstmt->analyze ? " ANALYZE" : "");
else
snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
"autovacuum: ANALYZE");
/*
* Report the qualified name of the relation.
- *
- * Paranoia is appropriate here in case relation was recently dropped ---
- * the lsyscache routines we just invoked will return NULL rather than
- * failing.
*/
! if (relname && nspname)
! {
! int len = strlen(activity);
! snprintf(activity + len, MAX_AUTOVAC_ACTIV_LEN - len,
! " %s.%s", nspname, relname);
! }
/* Set statement_timestamp() to current time for pg_stat_activity */
SetCurrentStatementStartTimestamp();
--- 2645,2672 ----
* bother to report "<IDLE>" or some such.
*/
static void
! autovac_report_activity(autovac_table *tab)
{
#define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
! char activity[MAX_AUTOVAC_ACTIV_LEN];
! int len;
/* Report the command and possible options */
! if (tab->at_dovacuum)
snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
"autovacuum: VACUUM%s",
! tab->at_doanalyze ? " ANALYZE" : "");
else
snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
"autovacuum: ANALYZE");
/*
* Report the qualified name of the relation.
*/
! len = strlen(activity);
! snprintf(activity + len, MAX_AUTOVAC_ACTIV_LEN - len,
! " %s.%s", tab->at_nspname, tab->at_relname);
/* Set statement_timestamp() to current time for pg_stat_activity */
SetCurrentStatementStartTimestamp();
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers