Per previous discussions, here are two functions to send INT and TERM

(cancel and terminate) signals to other backends.   They permit only INT
and TERM, and permits sending only to postgresql backends.

Magnus Hagander
This commit is contained in:
Bruce Momjian 2004-06-02 21:29:29 +00:00
parent de2c66539e
commit e8d9d68ca4
6 changed files with 95 additions and 7 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.63 2004/05/23 03:50:45 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.64 2004/06/02 21:29:28 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -463,6 +463,40 @@ TransactionIdIsInProgress(TransactionId xid)
return result;
}
/*
* IsBackendPid -- is a given pid a running backend
*/
bool
IsBackendPid(int pid)
{
bool result = false;
SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState;
int index;
LWLockAcquire(SInvalLock, LW_SHARED);
for (index = 0; index < segP->lastBackend; index++)
{
SHMEM_OFFSET pOffset = stateP[index].procStruct;
if (pOffset != INVALID_OFFSET)
{
PGPROC *proc = (PGPROC *) MAKE_PTR(pOffset);
if (proc->pid == pid)
{
result = true;
break;
}
}
}
LWLockRelease(SInvalLock);
return result;
}
/*
* GetOldestXmin -- returns oldest transaction that was running
* when any current transaction was started.

View File

@ -8,16 +8,18 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.33 2004/05/21 05:08:02 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.34 2004/06/02 21:29:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <sys/file.h>
#include <signal.h>
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "storage/sinval.h"
#include "utils/builtins.h"
@ -57,3 +59,47 @@ current_database(PG_FUNCTION_ARGS)
namestrcpy(db, get_database_name(MyDatabaseId));
PG_RETURN_NAME(db);
}
/*
* Functions to terminate a backend or cancel a query running on
* a different backend.
*/
static int pg_signal_backend(int pid, int sig)
{
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("only superuser can signal other backends"))));
if (!IsBackendPid(pid))
{
/* This is just a warning so a loop-through-resultset will not abort
* if one backend terminated on it's own during the run */
ereport(WARNING,
(errmsg("pid %i is not a postgresql backend",pid)));
return 0;
}
if (kill(pid, sig))
{
/* Again, just a warning to allow loops */
ereport(WARNING,
(errmsg("failed to send signal to backend %i: %m",pid)));
return 0;
}
return 1;
}
Datum
pg_terminate_backend(PG_FUNCTION_ARGS)
{
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
}
Datum
pg_cancel_backend(PG_FUNCTION_ARGS)
{
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
}

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.232 2004/05/26 18:37:33 momjian Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.233 2004/06/02 21:29:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200405262
#define CATALOG_VERSION_NO 200406021
#endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.333 2004/05/26 18:37:33 momjian Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.334 2004/06/02 21:29:29 momjian Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -2808,6 +2808,11 @@ DESCR("Statistics: Blocks fetched for database");
DATA(insert OID = 1945 ( pg_stat_get_db_blocks_hit PGNSP PGUID 12 f f t f s 1 20 "26" _null_ pg_stat_get_db_blocks_hit - _null_ ));
DESCR("Statistics: Blocks found in cache for database");
DATA(insert OID = 2171 ( pg_terminate_backend PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_terminate_backend - _null_ ));
DESCR("Terminate a backend process");
DATA(insert OID = 2172 ( pg_cancel_backend PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_cancel_backend - _null_ ));
DESCR("Cancel running query on a backend process");
DATA(insert OID = 1946 ( encode PGNSP PGUID 12 f f t f i 2 25 "17 25" _null_ binary_encode - _null_ ));
DESCR("Convert bytea value into some ascii-only text string");
DATA(insert OID = 1947 ( decode PGNSP PGUID 12 f f t f i 2 17 "25 25" _null_ binary_decode - _null_ ));

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.34 2004/05/23 03:50:45 tgl Exp $
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.35 2004/06/02 21:29:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -97,6 +97,7 @@ extern void ReceiveSharedInvalidMessages(
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
extern bool TransactionIdIsInProgress(TransactionId xid);
extern bool IsBackendPid(int pid);
extern TransactionId GetOldestXmin(bool allDbs);
extern int CountActiveBackends(void);
extern int CountEmptyBackendSlots(void);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.240 2004/05/26 18:35:46 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.241 2004/06/02 21:29:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -354,6 +354,8 @@ extern Datum float84ge(PG_FUNCTION_ARGS);
extern Datum nullvalue(PG_FUNCTION_ARGS);
extern Datum nonnullvalue(PG_FUNCTION_ARGS);
extern Datum current_database(PG_FUNCTION_ARGS);
extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
/* not_in.c */
extern Datum int4notin(PG_FUNCTION_ARGS);