From 10af02b912714a1cb423d100186b43b20142f008 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Fri, 29 Jun 2007 17:07:39 +0000 Subject: [PATCH] Arrange for SIGINT in autovacuum workers to cancel the current table and continue with the schedule. Change current uses of SIGINT to abort a worker into SIGTERM, which keeps the old behaviour of terminating the process. Patch from ITAGAKI Takahiro, with some editorializing of my own. --- src/backend/postmaster/autovacuum.c | 56 +++++++++++++++++++++++++---- src/backend/postmaster/postmaster.c | 4 +-- src/backend/storage/ipc/procarray.c | 4 +-- src/backend/tcop/postgres.c | 14 +++++--- 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index bc2dfee28f..2739e2484f 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -55,7 +55,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.51 2007/06/25 16:09:03 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.52 2007/06/29 17:07:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -75,6 +75,7 @@ #include "catalog/namespace.h" #include "catalog/pg_autovacuum.h" #include "catalog/pg_database.h" +#include "commands/dbcommands.h" #include "commands/vacuum.h" #include "libpq/hba.h" #include "libpq/pqsignal.h" @@ -2025,12 +2026,53 @@ next_worker: autovac_balance_cost(); LWLockRelease(AutovacuumLock); - /* have at it */ - autovacuum_do_vac_analyze(tab->at_relid, - tab->at_dovacuum, - tab->at_doanalyze, - tab->at_freeze_min_age, - bstrategy); + /* + * We will abort vacuuming the current table if we are interrupted, and + * continue with the next one in schedule; but if anything else + * happens, we will do our usual error handling which is to cause the + * worker process to exit. + */ + PG_TRY(); + { + /* have at it */ + autovacuum_do_vac_analyze(tab->at_relid, + tab->at_dovacuum, + tab->at_doanalyze, + tab->at_freeze_min_age, + bstrategy); + } + PG_CATCH(); + { + ErrorData *errdata; + + MemoryContextSwitchTo(TopTransactionContext); + errdata = CopyErrorData(); + + /* + * If we errored out due to a cancel request, abort and restart the + * transaction and go to the next table. Otherwise rethrow the + * error so that the outermost handler deals with it. + */ + if (errdata->sqlerrcode == ERRCODE_QUERY_CANCELED) + { + HOLD_INTERRUPTS(); + elog(LOG, "cancelling autovacuum of table \"%s.%s.%s\"", + get_database_name(MyDatabaseId), + get_namespace_name(get_rel_namespace(tab->at_relid)), + get_rel_name(tab->at_relid)); + + AbortOutOfAnyTransaction(); + FlushErrorState(); + + /* restart our transaction for the following operations */ + StartTransactionCommand(); + RESUME_INTERRUPTS(); + } + else + PG_RE_THROW(); + } + PG_END_TRY(); + /* be tidy */ pfree(tab); } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index cb060878a9..e68546e3e8 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.528 2007/06/25 16:09:03 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.529 2007/06/29 17:07:39 alvherre Exp $ * * NOTES * @@ -1875,7 +1875,7 @@ pmdie(SIGNAL_ARGS) /* autovacuum workers are shut down immediately */ if (DLGetHead(BackendList)) - SignalSomeChildren(SIGINT, true); + SignalSomeChildren(SIGTERM, true); if (DLGetHead(BackendList)) break; /* let reaper() handle this */ diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 9d290ba973..9819adffcb 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -23,7 +23,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.26 2007/06/07 21:45:59 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.27 2007/06/29 17:07:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -1008,7 +1008,7 @@ CheckOtherDBBackends(Oid databaseId) */ LWLockRelease(ProcArrayLock); - (void) kill(autopid, SIGINT); /* ignore any error */ + (void) kill(autopid, SIGTERM); /* ignore any error */ break; } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 94fd65e5d4..c5ede14004 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.534 2007/06/23 22:12:52 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.535 2007/06/29 17:07:39 alvherre Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -51,6 +51,7 @@ #include "optimizer/planner.h" #include "parser/analyze.h" #include "parser/parser.h" +#include "postmaster/autovacuum.h" #include "rewrite/rewriteHandler.h" #include "storage/freespace.h" #include "storage/ipc.h" @@ -2540,9 +2541,14 @@ ProcessInterrupts(void) ImmediateInterruptOK = false; /* not idle anymore */ DisableNotifyInterrupt(); DisableCatchupInterrupt(); - ereport(FATAL, - (errcode(ERRCODE_ADMIN_SHUTDOWN), - errmsg("terminating connection due to administrator command"))); + if (IsAutoVacuumWorkerProcess()) + ereport(FATAL, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating autovacuum process due to administrator command"))); + else + ereport(FATAL, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection due to administrator command"))); } if (QueryCancelPending) {