Commit 10af02b9 authored by Alvaro Herrera's avatar Alvaro Herrera

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.
parent c786796d
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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;
}
......
......@@ -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)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment