diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index 570feab25e6e6cb7008926ea69eb63b64f836830..856d0f0a73f2b65218a69212d33e945b79f079f9 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -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. diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 673b175bbc042c4a3fed81304b381d13563a3db8..8ab6953cb02c151148a9fabc449b0b9c157128b9 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -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)); +} diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index f0c2f8269197ce965166dbd1daeb64b7275d7da3..bf6ded488cad8cfc5a0564dd794bdeb951f61d7e 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index c87eb2155658212cc0ea0e9b4b992d474f3bd9f4..cb3279747b03a934c4d0ef4cdd96850540ca3b61 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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_ )); diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h index a1c731024cf8c4d51550af8dca33e475f010384b..84769200504450f8c5089c028465e8429c9592ba 100644 --- a/src/include/storage/sinval.h +++ b/src/include/storage/sinval.h @@ -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); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 267ededb1303af7684e6ecbdce148946dc1f2744..1fc26e69a1f5d59f3dce1950f2121bbd443d34b1 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -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);