Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit46c5a21

Browse files
committed
Avoid crashing when a table is deleted while we're on the process of checking
it.Per report from Tom Lane based on buildfarm evidence.
1 parenta41f73a commit46c5a21

File tree

1 file changed

+45
-49
lines changed

1 file changed

+45
-49
lines changed

‎src/backend/postmaster/autovacuum.c

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.80 2008/07/0102: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
176176
intat_vacuum_cost_delay;
177177
intat_vacuum_cost_limit;
178178
boolat_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,
282285
PgStat_StatTabEntry*tabentry,bool*dovacuum,
283286
bool*doanalyze,bool*wraparound);
284287

285-
staticvoidautovacuum_do_vac_analyze(Oidrelid,booldovacuum,
286-
booldoanalyze,intfreeze_min_age,
287-
boolfor_wraparound,
288+
staticvoidautovacuum_do_vac_analyze(autovac_table*tab,
288289
BufferAccessStrategybstrategy);
289290
staticHeapTupleget_pg_autovacuum_tuple_relid(RelationavRel,Oidrelid);
290291
staticPgStat_StatTabEntry*get_pgstat_tabentry_relid(Oidrelid,boolisshared,
291292
PgStat_StatDBEntry*shared,
292293
PgStat_StatDBEntry*dbentry);
293-
staticvoidautovac_report_activity(VacuumStmt*vacstmt,Oidrelid);
294+
staticvoidautovac_report_activity(autovac_table*tab);
294295
staticvoidavl_sighup_handler(SIGNAL_ARGS);
295296
staticvoidavl_sigusr1_handler(SIGNAL_ARGS);
296297
staticvoidavl_sigterm_handler(SIGNAL_ARGS);
@@ -2061,9 +2062,6 @@ do_autovacuum(void)
20612062
autovac_table*tab;
20622063
WorkerInfoworker;
20632064
boolskipit;
2064-
char*datname,
2065-
*nspname,
2066-
*relname;
20672065

20682066
CHECK_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 */
21772179
MemoryContextSwitchTo(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)
21992196
HOLD_INTERRUPTS();
22002197
if (tab->at_dovacuum)
22012198
errcontext("automatic vacuum of table \"%s.%s.%s\"",
2202-
datname,nspname,relname);
2199+
tab->at_datname,tab->at_nspname,tab->at_relname);
22032200
else
22042201
errcontext("automatic analyze of table \"%s.%s.%s\"",
2205-
datname,nspname,relname);
2202+
tab->at_datname,tab->at_nspname,tab->at_relname);
22062203
EmitErrorReport();
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);
22222226
pfree(tab);
2223-
pfree(datname);
2224-
pfree(nspname);
2225-
pfree(relname);
22262227

22272228
/* remove my info from shared memory */
22282229
LWLockAcquire(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
*/
23032306
staticautovac_table*
23042307
table_recheck_autovac(Oidrelid)
@@ -2437,6 +2440,9 @@ table_recheck_autovac(Oid relid)
24372440
tab->at_vacuum_cost_limit=vac_cost_limit;
24382441
tab->at_vacuum_cost_delay=vac_cost_delay;
24392442
tab->at_wraparound=wraparound||toast_wraparound;
2443+
tab->at_relname=NULL;
2444+
tab->at_nspname=NULL;
2445+
tab->at_datname=NULL;
24402446
}
24412447

24422448
heap_close(avRel,AccessShareLock);
@@ -2607,8 +2613,7 @@ relation_needs_vacanalyze(Oid relid,
26072613
*Vacuum and/or analyze the specified table
26082614
*/
26092615
staticvoid
2610-
autovacuum_do_vac_analyze(Oidrelid,booldovacuum,booldoanalyze,
2611-
intfreeze_min_age,boolfor_wraparound,
2616+
autovacuum_do_vac_analyze(autovac_table*tab,
26122617
BufferAccessStrategybstrategy)
26132618
{
26142619
VacuumStmtvacstmt;
@@ -2617,18 +2622,18 @@ autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
26172622
MemSet(&vacstmt,0,sizeof(vacstmt));
26182623

26192624
vacstmt.type=T_VacuumStmt;
2620-
vacstmt.vacuum=dovacuum;
2625+
vacstmt.vacuum=tab->at_dovacuum;
26212626
vacstmt.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;
26242629
vacstmt.verbose= false;
26252630
vacstmt.relation=NULL;/* not used since we pass a relid */
26262631
vacstmt.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
*/
26452650
staticvoid
2646-
autovac_report_activity(VacuumStmt*vacstmt,Oidrelid)
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
#defineMAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
2652-
charactivity[MAX_AUTOVAC_ACTIV_LEN];
2654+
charactivity[MAX_AUTOVAC_ACTIV_LEN];
2655+
intlen;
26532656

26542657
/* Report the command and possible options */
2655-
if (vacstmt->vacuum)
2658+
if (tab->at_dovacuum)
26562659
snprintf(activity,MAX_AUTOVAC_ACTIV_LEN,
26572660
"autovacuum: VACUUM%s",
2658-
vacstmt->analyze ?" ANALYZE" :"");
2661+
tab->at_doanalyze ?" ANALYZE" :"");
26592662
else
26602663
snprintf(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-
intlen=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 */
26792675
SetCurrentStatementStartTimestamp();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp