Skip to content

Commit 18b286f

Browse files
committed
Add pg_terminate_backend() to allow terminating only a single session.
1 parent fcf053d commit 18b286f

File tree

7 files changed

+90
-24
lines changed

7 files changed

+90
-24
lines changed

doc/src/sgml/func.sgml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.430 2008/04/14 17:05:32 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.431 2008/04/15 13:55:11 momjian Exp $ -->
22

33
<chapter id="functions">
44
<title>Functions and Operators</title>
@@ -11848,6 +11848,9 @@ SELECT set_config('log_statement_stats', 'off', false);
1184811848
<indexterm>
1184911849
<primary>pg_cancel_backend</primary>
1185011850
</indexterm>
11851+
<indexterm>
11852+
<primary>pg_terminate_backend</primary>
11853+
</indexterm>
1185111854
<indexterm>
1185211855
<primary>pg_reload_conf</primary>
1185311856
</indexterm>
@@ -11883,6 +11886,13 @@ SELECT set_config('log_statement_stats', 'off', false);
1188311886
<entry><type>boolean</type></entry>
1188411887
<entry>Cancel a backend's current query</entry>
1188511888
</row>
11889+
<row>
11890+
<entry>
11891+
<literal><function>pg_terminate_backend</function>(<parameter>pid</parameter> <type>int</>)</literal>
11892+
</entry>
11893+
<entry><type>boolean</type></entry>
11894+
<entry>Terminate a backend</entry>
11895+
</row>
1188611896
<row>
1188711897
<entry>
1188811898
<literal><function>pg_reload_conf</function>()</literal>
@@ -11907,9 +11917,10 @@ SELECT set_config('log_statement_stats', 'off', false);
1190711917
</para>
1190811918

1190911919
<para>
11910-
<function>pg_cancel_backend</> sends a query cancel
11911-
(<systemitem>SIGINT</>) signal to a backend process identified by
11912-
process ID. The process ID of an active backend can be found from
11920+
<function>pg_cancel_backend</> and <function>pg_terminate_backend</>
11921+
send a query cancel (<systemitem>SIGINT</>) signal to a backend process
11922+
identified by process ID. The
11923+
process ID of an active backend can be found from
1191311924
the <structfield>procpid</structfield> column in the
1191411925
<structname>pg_stat_activity</structname> view, or by listing the
1191511926
<command>postgres</command> processes on the server with

doc/src/sgml/runtime.sgml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.411 2008/03/31 02:43:14 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.412 2008/04/15 13:55:11 momjian Exp $ -->
22

33
<chapter Id="runtime">
44
<title>Operating System Environment</title>
@@ -1372,6 +1372,13 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
13721372
well.
13731373
</para>
13741374
</important>
1375+
1376+
<para>
1377+
To terminate a session while allowing other sessions to continue, use
1378+
<function>pg_terminate_backend()</> (<xref
1379+
linkend="functions-admin-signal-table">) rather than sending a signal
1380+
to the child process.
1381+
</para>
13751382
</sect1>
13761383

13771384
<sect1 id="preventing-server-spoofing">

src/backend/tcop/postgres.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.548 2008/04/02 18:31:50 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.549 2008/04/15 13:55:11 momjian Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -2541,7 +2541,8 @@ StatementCancelHandler(SIGNAL_ARGS)
25412541
* waiting for input, however.
25422542
*/
25432543
if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
2544-
CritSectionCount == 0 && !DoingCommandRead)
2544+
CritSectionCount == 0 &&
2545+
(!DoingCommandRead || MyProc->terminate))
25452546
{
25462547
/* bump holdoff count to make ProcessInterrupts() a no-op */
25472548
/* until we are done getting ready for it */
@@ -2621,6 +2622,10 @@ ProcessInterrupts(void)
26212622
ereport(ERROR,
26222623
(errcode(ERRCODE_QUERY_CANCELED),
26232624
errmsg("canceling autovacuum task")));
2625+
else if (MyProc->terminate)
2626+
ereport(ERROR,
2627+
(errcode(ERRCODE_ADMIN_SHUTDOWN),
2628+
errmsg("terminating backend due to administrator command")));
26242629
else
26252630
ereport(ERROR,
26262631
(errcode(ERRCODE_QUERY_CANCELED),
@@ -3459,6 +3464,9 @@ PostgresMain(int argc, char *argv[], const char *username)
34593464
/* We don't have a transaction command open anymore */
34603465
xact_started = false;
34613466

3467+
if (MyProc->terminate)
3468+
die(SIGINT);
3469+
34623470
/* Now we can allow interrupts again */
34633471
RESUME_INTERRUPTS();
34643472
}

src/backend/utils/adt/misc.c

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.59 2008/04/04 16:57:21 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.60 2008/04/15 13:55:11 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -27,6 +27,7 @@
2727
#include "postmaster/syslogger.h"
2828
#include "storage/fd.h"
2929
#include "storage/pmsignal.h"
30+
#include "storage/proc.h"
3031
#include "storage/procarray.h"
3132
#include "utils/builtins.h"
3233
#include "tcop/tcopprot.h"
@@ -89,7 +90,7 @@ current_query(PG_FUNCTION_ARGS)
8990
* Functions to send signals to other backends.
9091
*/
9192
static bool
92-
pg_signal_backend(int pid, int sig)
93+
pg_signal_check(int pid)
9394
{
9495
if (!superuser())
9596
ereport(ERROR,
@@ -106,7 +107,16 @@ pg_signal_backend(int pid, int sig)
106107
(errmsg("PID %d is not a PostgreSQL server process", pid)));
107108
return false;
108109
}
110+
else
111+
return true;
112+
}
109113

114+
/*
115+
* Functions to send signals to other backends.
116+
*/
117+
static bool
118+
pg_signal_backend(int pid, int sig)
119+
{
110120
/* If we have setsid(), signal the backend's whole process group */
111121
#ifdef HAVE_SETSID
112122
if (kill(-pid, sig))
@@ -125,7 +135,43 @@ pg_signal_backend(int pid, int sig)
125135
Datum
126136
pg_cancel_backend(PG_FUNCTION_ARGS)
127137
{
128-
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT));
138+
int pid = PG_GETARG_INT32(0);
139+
140+
if (pg_signal_check(pid))
141+
PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
142+
else
143+
PG_RETURN_BOOL(false);
144+
}
145+
146+
/*
147+
* To cleanly terminate a backend, we set PGPROC(pid)->terminate
148+
* then send a cancel signal. We get ProcArrayLock only when
149+
* setting PGPROC->terminate so the function might fail in
150+
* several places, but that is fine because in those cases the
151+
* backend is already gone.
152+
*/
153+
Datum
154+
pg_terminate_backend(PG_FUNCTION_ARGS)
155+
{
156+
int pid = PG_GETARG_INT32(0);
157+
volatile PGPROC *term_proc;
158+
159+
/* Is this the super-user, and can we find the PGPROC entry for the pid? */
160+
if (pg_signal_check(pid) && (term_proc = BackendPidGetProc(pid)) != NULL)
161+
{
162+
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
163+
/* Recheck now that we have the ProcArray lock. */
164+
if (term_proc->pid == pid)
165+
{
166+
term_proc->terminate = true;
167+
LWLockRelease(ProcArrayLock);
168+
PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
169+
}
170+
else
171+
LWLockRelease(ProcArrayLock);
172+
}
173+
174+
PG_RETURN_BOOL(false);
129175
}
130176

131177
Datum
@@ -169,17 +215,6 @@ pg_rotate_logfile(PG_FUNCTION_ARGS)
169215
PG_RETURN_BOOL(true);
170216
}
171217

172-
#ifdef NOT_USED
173-
174-
/* Disabled in 8.0 due to reliability concerns; FIXME someday */
175-
Datum
176-
pg_terminate_backend(PG_FUNCTION_ARGS)
177-
{
178-
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM));
179-
}
180-
#endif
181-
182-
183218
/* Function to find out which databases make use of a tablespace */
184219

185220
typedef struct

src/include/catalog/pg_proc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.489 2008/04/14 17:05:33 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.490 2008/04/15 13:55:11 momjian Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -3157,6 +3157,8 @@ DESCR("is schema another session's temp schema?");
31573157

31583158
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_ ));
31593159
DESCR("cancel a server process' current query");
3160+
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_ ));
3161+
DESCR("terminate a server process");
31603162
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_ ));
31613163
DESCR("prepare for taking an online backup");
31623164
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_ ));

src/include/storage/proc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.104 2008/01/26 19:55:08 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/proc.h,v 1.105 2008/04/15 13:55:12 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -91,6 +91,8 @@ struct PGPROC
9191

9292
bool inCommit; /* true if within commit critical section */
9393

94+
bool terminate; /* admin requested termination */
95+
9496
uint8 vacuumFlags; /* vacuum-related flags, see above */
9597

9698
/* Info about LWLock the process is currently waiting for, if any. */

src/include/utils/builtins.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.312 2008/04/04 18:45:36 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.313 2008/04/15 13:55:12 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -416,6 +416,7 @@ extern Datum nonnullvalue(PG_FUNCTION_ARGS);
416416
extern Datum current_database(PG_FUNCTION_ARGS);
417417
extern Datum current_query(PG_FUNCTION_ARGS);
418418
extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
419+
extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
419420
extern Datum pg_reload_conf(PG_FUNCTION_ARGS);
420421
extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS);
421422
extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)