Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.432
diff -c -c -r1.432 func.sgml
*** doc/src/sgml/func.sgml 15 Apr 2008 20:28:46 -0000 1.432
--- doc/src/sgml/func.sgml 16 Apr 2008 03:59:20 -0000
***************
*** 11849,11854 ****
--- 11849,11857 ----
pg_cancel_backend
+ pg_terminate_backend
+
+
pg_reload_conf
***************
*** 11885,11890 ****
--- 11888,11900 ----
+ pg_terminate_backend(pid int>)
+
+ boolean
+ Terminate a backend
+
+
+
pg_reload_conf()
boolean
***************
*** 11907,11915 ****
! pg_cancel_backend> sends a query cancel
! (SIGINT>) signal to a backend process identified by
! process ID. The process ID of an active backend can be found from
the procpid column in the
pg_stat_activity view, or by listing the
postgres processes on the server with
--- 11917,11926 ----
! pg_cancel_backend> and pg_terminate_backend>
! send a query cancel (SIGINT>) signal to a backend process
! identified by process ID. The
! process ID of an active backend can be found from
the procpid column in the
pg_stat_activity view, or by listing the
postgres processes on the server with
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v
retrieving revision 1.413
diff -c -c -r1.413 runtime.sgml
*** doc/src/sgml/runtime.sgml 15 Apr 2008 20:28:46 -0000 1.413
--- doc/src/sgml/runtime.sgml 16 Apr 2008 03:59:20 -0000
***************
*** 1372,1377 ****
--- 1372,1384 ----
well.
+
+
+ To terminate a session while allowing other sessions to continue, use
+ pg_terminate_backend()> () rather than sending a signal
+ to the child process.
+
Index: src/backend/access/transam/twophase.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/transam/twophase.c,v
retrieving revision 1.41
diff -c -c -r1.41 twophase.c
*** src/backend/access/transam/twophase.c 25 Mar 2008 22:42:42 -0000 1.41
--- src/backend/access/transam/twophase.c 16 Apr 2008 03:59:20 -0000
***************
*** 283,288 ****
--- 283,289 ----
gxact->proc.databaseId = databaseid;
gxact->proc.roleId = owner;
gxact->proc.inCommit = false;
+ gxact->proc.terminate = false;
gxact->proc.vacuumFlags = 0;
gxact->proc.lwWaiting = false;
gxact->proc.lwExclusive = false;
Index: src/backend/storage/ipc/procarray.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/storage/ipc/procarray.c,v
retrieving revision 1.43
diff -c -c -r1.43 procarray.c
*** src/backend/storage/ipc/procarray.c 26 Mar 2008 18:48:59 -0000 1.43
--- src/backend/storage/ipc/procarray.c 16 Apr 2008 03:59:20 -0000
***************
*** 935,941 ****
* answer to be used ...
*/
PGPROC *
! BackendPidGetProc(int pid)
{
PGPROC *result = NULL;
ProcArrayStruct *arrayP = procArray;
--- 935,941 ----
* answer to be used ...
*/
PGPROC *
! BackendPidGetProc(int pid, bool want_shlock)
{
PGPROC *result = NULL;
ProcArrayStruct *arrayP = procArray;
***************
*** 957,964 ****
}
}
! LWLockRelease(ProcArrayLock);
!
return result;
}
--- 957,966 ----
}
}
! /* Do they want the proc returned with an shared lock? */
! if (!result || !want_shlock)
! LWLockRelease(ProcArrayLock);
!
return result;
}
***************
*** 1009,1015 ****
bool
IsBackendPid(int pid)
{
! return (BackendPidGetProc(pid) != NULL);
}
--- 1011,1017 ----
bool
IsBackendPid(int pid)
{
! return (BackendPidGetProc(pid, false) != NULL);
}
Index: src/backend/storage/lmgr/proc.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v
retrieving revision 1.199
diff -c -c -r1.199 proc.c
*** src/backend/storage/lmgr/proc.c 26 Jan 2008 19:55:08 -0000 1.199
--- src/backend/storage/lmgr/proc.c 16 Apr 2008 03:59:20 -0000
***************
*** 291,296 ****
--- 291,297 ----
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inCommit = false;
+ MyProc->terminate = false;
MyProc->vacuumFlags = 0;
if (IsAutoVacuumWorkerProcess())
MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
***************
*** 430,435 ****
--- 431,437 ----
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
MyProc->inCommit = false;
+ MyProc->terminate = false;
/* we don't set the "is autovacuum" flag in the launcher */
MyProc->vacuumFlags = 0;
MyProc->lwWaiting = false;
***************
*** 1275,1281 ****
void
ProcSendSignal(int pid)
{
! PGPROC *proc = BackendPidGetProc(pid);
if (proc != NULL)
PGSemaphoreUnlock(&proc->sem);
--- 1277,1283 ----
void
ProcSendSignal(int pid)
{
! PGPROC *proc = BackendPidGetProc(pid, false);
if (proc != NULL)
PGSemaphoreUnlock(&proc->sem);
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/tcop/postgres.c,v
retrieving revision 1.550
diff -c -c -r1.550 postgres.c
*** src/backend/tcop/postgres.c 15 Apr 2008 20:28:46 -0000 1.550
--- src/backend/tcop/postgres.c 16 Apr 2008 03:59:23 -0000
***************
*** 2541,2547 ****
* waiting for input, however.
*/
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
! CritSectionCount == 0 && !DoingCommandRead)
{
/* bump holdoff count to make ProcessInterrupts() a no-op */
/* until we are done getting ready for it */
--- 2541,2548 ----
* waiting for input, however.
*/
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
! CritSectionCount == 0 &&
! (!DoingCommandRead || MyProc->terminate))
{
/* bump holdoff count to make ProcessInterrupts() a no-op */
/* until we are done getting ready for it */
***************
*** 2621,2626 ****
--- 2622,2631 ----
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),
***************
*** 3492,3497 ****
--- 3497,3505 ----
initStringInfo(&input_message);
+ if (MyProc->terminate)
+ proc_exit(0);
+
/*
* (1) If we've reached idle state, tell the frontend we're ready for
* a new query.
Index: src/backend/utils/adt/misc.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v
retrieving revision 1.61
diff -c -c -r1.61 misc.c
*** src/backend/utils/adt/misc.c 15 Apr 2008 20:28:46 -0000 1.61
--- src/backend/utils/adt/misc.c 16 Apr 2008 03:59:23 -0000
***************
*** 27,32 ****
--- 27,33 ----
#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,95 ****
* Functions to send signals to other backends.
*/
static bool
! pg_signal_backend(int pid, int sig)
{
if (!superuser())
ereport(ERROR,
--- 90,96 ----
* Functions to send signals to other backends.
*/
static bool
! pg_signal_check(int pid)
{
if (!superuser())
ereport(ERROR,
***************
*** 106,112 ****
--- 107,122 ----
(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,131 ****
Datum
pg_cancel_backend(PG_FUNCTION_ARGS)
{
! PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT));
}
Datum
--- 135,168 ----
Datum
pg_cancel_backend(PG_FUNCTION_ARGS)
{
! 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. SIGTERM isn't 100% safe for
! * cases where other backend will continue to run.
! */
! 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, true)) != NULL)
! {
! term_proc->terminate = true;
! LWLockRelease(ProcArrayLock);
! PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
! }
!
! PG_RETURN_BOOL(false);
}
Datum
***************
*** 169,185 ****
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
--- 206,211 ----
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.491
diff -c -c -r1.491 pg_proc.h
*** src/include/catalog/pg_proc.h 15 Apr 2008 20:28:46 -0000 1.491
--- src/include/catalog/pg_proc.h 16 Apr 2008 03:59:23 -0000
***************
*** 3157,3162 ****
--- 3157,3164 ----
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_ ));
Index: src/include/storage/proc.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/storage/proc.h,v
retrieving revision 1.106
diff -c -c -r1.106 proc.h
*** src/include/storage/proc.h 15 Apr 2008 20:28:47 -0000 1.106
--- src/include/storage/proc.h 16 Apr 2008 03:59:25 -0000
***************
*** 91,96 ****
--- 91,98 ----
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. */
Index: src/include/storage/procarray.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/storage/procarray.h,v
retrieving revision 1.21
diff -c -c -r1.21 procarray.h
*** src/include/storage/procarray.h 26 Mar 2008 16:20:48 -0000 1.21
--- src/include/storage/procarray.h 16 Apr 2008 03:59:25 -0000
***************
*** 35,41 ****
extern int GetTransactionsInCommit(TransactionId **xids_p);
extern bool HaveTransactionsInCommit(TransactionId *xids, int nxids);
! extern PGPROC *BackendPidGetProc(int pid);
extern int BackendXidGetPid(TransactionId xid);
extern bool IsBackendPid(int pid);
--- 35,41 ----
extern int GetTransactionsInCommit(TransactionId **xids_p);
extern bool HaveTransactionsInCommit(TransactionId *xids, int nxids);
! extern PGPROC *BackendPidGetProc(int pid, bool shlock);
extern int BackendXidGetPid(TransactionId xid);
extern bool IsBackendPid(int pid);
Index: src/include/utils/builtins.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.314
diff -c -c -r1.314 builtins.h
*** src/include/utils/builtins.h 15 Apr 2008 20:28:47 -0000 1.314
--- src/include/utils/builtins.h 16 Apr 2008 03:59:25 -0000
***************
*** 416,421 ****
--- 416,422 ----
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);