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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy