mirror of
https://github.com/postgres/postgres.git
synced 2025-07-20 05:03:10 +03:00
Add pg_terminate_backend() to allow terminating only a single session.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.548 2008/04/02 18:31:50 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.549 2008/04/15 13:55:11 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -2541,7 +2541,8 @@ StatementCancelHandler(SIGNAL_ARGS)
|
||||
* waiting for input, however.
|
||||
*/
|
||||
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
|
||||
CritSectionCount == 0 && !DoingCommandRead)
|
||||
CritSectionCount == 0 &&
|
||||
(!DoingCommandRead || MyProc->terminate))
|
||||
{
|
||||
/* bump holdoff count to make ProcessInterrupts() a no-op */
|
||||
/* until we are done getting ready for it */
|
||||
@ -2621,6 +2622,10 @@ ProcessInterrupts(void)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_QUERY_CANCELED),
|
||||
errmsg("canceling autovacuum task")));
|
||||
else if (MyProc->terminate)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ADMIN_SHUTDOWN),
|
||||
errmsg("terminating backend due to administrator command")));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_QUERY_CANCELED),
|
||||
@ -3459,6 +3464,9 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||
/* We don't have a transaction command open anymore */
|
||||
xact_started = false;
|
||||
|
||||
if (MyProc->terminate)
|
||||
die(SIGINT);
|
||||
|
||||
/* Now we can allow interrupts again */
|
||||
RESUME_INTERRUPTS();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.59 2008/04/04 16:57:21 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.60 2008/04/15 13:55:11 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,6 +27,7 @@
|
||||
#include "postmaster/syslogger.h"
|
||||
#include "storage/fd.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
@ -89,7 +90,7 @@ current_query(PG_FUNCTION_ARGS)
|
||||
* Functions to send signals to other backends.
|
||||
*/
|
||||
static bool
|
||||
pg_signal_backend(int pid, int sig)
|
||||
pg_signal_check(int pid)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
@ -106,7 +107,16 @@ pg_signal_backend(int pid, int sig)
|
||||
(errmsg("PID %d is not a PostgreSQL server process", pid)));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to send signals to other backends.
|
||||
*/
|
||||
static bool
|
||||
pg_signal_backend(int pid, int sig)
|
||||
{
|
||||
/* If we have setsid(), signal the backend's whole process group */
|
||||
#ifdef HAVE_SETSID
|
||||
if (kill(-pid, sig))
|
||||
@ -125,7 +135,43 @@ pg_signal_backend(int pid, int sig)
|
||||
Datum
|
||||
pg_cancel_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT));
|
||||
int pid = PG_GETARG_INT32(0);
|
||||
|
||||
if (pg_signal_check(pid))
|
||||
PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
|
||||
else
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* To cleanly terminate a backend, we set PGPROC(pid)->terminate
|
||||
* then send a cancel signal. We get ProcArrayLock only when
|
||||
* setting PGPROC->terminate so the function might fail in
|
||||
* several places, but that is fine because in those cases the
|
||||
* backend is already gone.
|
||||
*/
|
||||
Datum
|
||||
pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int pid = PG_GETARG_INT32(0);
|
||||
volatile PGPROC *term_proc;
|
||||
|
||||
/* Is this the super-user, and can we find the PGPROC entry for the pid? */
|
||||
if (pg_signal_check(pid) && (term_proc = BackendPidGetProc(pid)) != NULL)
|
||||
{
|
||||
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||
/* Recheck now that we have the ProcArray lock. */
|
||||
if (term_proc->pid == pid)
|
||||
{
|
||||
term_proc->terminate = true;
|
||||
LWLockRelease(ProcArrayLock);
|
||||
PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
|
||||
}
|
||||
else
|
||||
LWLockRelease(ProcArrayLock);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
Datum
|
||||
@ -169,17 +215,6 @@ pg_rotate_logfile(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
/* Disabled in 8.0 due to reliability concerns; FIXME someday */
|
||||
Datum
|
||||
pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Function to find out which databases make use of a tablespace */
|
||||
|
||||
typedef struct
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.489 2008/04/14 17:05:33 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.490 2008/04/15 13:55:11 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -3157,6 +3157,8 @@ DESCR("is schema another session's temp schema?");
|
||||
|
||||
DATA(insert OID = 2171 ( pg_cancel_backend PGNSP PGUID 12 1 0 f f t f v 1 16 "23" _null_ _null_ _null_ pg_cancel_backend - _null_ _null_ ));
|
||||
DESCR("cancel a server process' current query");
|
||||
DATA(insert OID = 2096 ( pg_terminate_backend PGNSP PGUID 12 1 0 f f t f v 1 16 "23" _null_ _null_ _null_ pg_terminate_backend - _null_ _null_ ));
|
||||
DESCR("terminate a server process");
|
||||
DATA(insert OID = 2172 ( pg_start_backup PGNSP PGUID 12 1 0 f f t f v 1 25 "25" _null_ _null_ _null_ pg_start_backup - _null_ _null_ ));
|
||||
DESCR("prepare for taking an online backup");
|
||||
DATA(insert OID = 2173 ( pg_stop_backup PGNSP PGUID 12 1 0 f f t f v 0 25 "" _null_ _null_ _null_ pg_stop_backup - _null_ _null_ ));
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.104 2008/01/26 19:55:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.105 2008/04/15 13:55:12 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -91,6 +91,8 @@ struct PGPROC
|
||||
|
||||
bool inCommit; /* true if within commit critical section */
|
||||
|
||||
bool terminate; /* admin requested termination */
|
||||
|
||||
uint8 vacuumFlags; /* vacuum-related flags, see above */
|
||||
|
||||
/* Info about LWLock the process is currently waiting for, if any. */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.312 2008/04/04 18:45:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.313 2008/04/15 13:55:12 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -416,6 +416,7 @@ extern Datum nonnullvalue(PG_FUNCTION_ARGS);
|
||||
extern Datum current_database(PG_FUNCTION_ARGS);
|
||||
extern Datum current_query(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_reload_conf(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS);
|
||||
extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS);
|
||||
|
Reference in New Issue
Block a user