Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita0659e3

Browse files
committed
From: Tom Lane <tgl@sss.pgh.pa.us>Making PQrequestCancel safe to call in a signal handler turned out to bemuch easier than I feared. So here are the diffs.Some notes: * I modified the postmaster's packet "iodone" callback interface to allow the callback routine to return a continue-or-drop-connection return code; this was necessary to allow the connection to be closed after receiving a Cancel, rather than proceeding to launch a new backend... Being a neatnik, I also made the iodone proc have a typechecked parameter list. * I deleted all code I could find that had to do with OOB. * I made some edits to ensure that all signals mentioned in the code are referred to symbolically not by numbers ("SIGUSR2" not "2"). I think Bruce may have already done at least some of the same edits; I hope that merging these patches is not too painful.
1 parent8bf6182 commita0659e3

File tree

20 files changed

+597
-287
lines changed

20 files changed

+597
-287
lines changed

‎doc/src/sgml/protocol.sgml

Lines changed: 217 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<FirstName>Phil</FirstName>
55
<Surname>Thompson</Surname>
66
</Author>
7-
<Date>1998-05-04</Date>
7+
<Date>1998-07-07</Date>
88
</DocInfo>
99
<Title>Frontend/Backend Protocol</Title>
1010

@@ -54,8 +54,10 @@ invalid database name).
5454

5555
<Para>
5656
Subsequent communications are query and result packets exchanged between the
57-
frontend and the backend. The postmaster takes no further part in the
58-
communication.
57+
frontend and the backend. The postmaster takes no further part in ordinary
58+
query/result communication. (However, the postmaster is involved when the
59+
frontend wishes to cancel a query currently being executed by its backend.
60+
Further details about that appear below.)
5961

6062
<Para>
6163
When the frontend wishes to disconnect it sends an appropriate packet and
@@ -182,6 +184,20 @@ The possible messages from the backend during this phase are:
182184
<Para>
183185
<VariableList>
184186
<VarListEntry>
187+
<Term>
188+
BackendKeyData
189+
</Term>
190+
<ListItem>
191+
<Para>
192+
This message is issued after successful backend startup.
193+
It provides secret-key data that the frontend must save
194+
if it wants to be able to issue cancel requests later.
195+
The frontend should not respond to this message, but should
196+
continue listening for a ReadyForQuery message.
197+
</Para>
198+
</ListItem>
199+
</VarListEntry>
200+
<VarListEntry>
185201
<Term>
186202
ReadyForQuery
187203
</Term>
@@ -218,6 +234,14 @@ The possible messages from the backend during this phase are:
218234
</VariableList>
219235
</Para>
220236

237+
<Para>
238+
The ReadyForQuery message is the same one that the backend will issue after
239+
each query cycle. Depending on the coding needs of the frontend, it is
240+
reasonable to consider ReadyForQuery as starting a query cycle (and then
241+
BackendKeyData indicates successful conclusion of the startup phase),
242+
or to consider ReadyForQuery as ending the startup phase and each subsequent
243+
query cycle.
244+
221245

222246
<Sect2>
223247
<Title>Query</Title>
@@ -453,7 +477,7 @@ NotificationResponse messages at any time; see below.
453477
<Para>
454478
If a frontend issues a listen(l) command, then the backend will send a
455479
NotificationResponse message (not to be confused with NoticeResponse!)
456-
whenever a notify(l) command is executed for the samerelation name.
480+
whenever a notify(l) command is executed for the samenotification name.
457481

458482
<Para>
459483
Notification responses are permitted at any point in the protocol (after
@@ -470,38 +494,86 @@ NotificationResponse messages even when it is not engaged in a query.
470494
</Term>
471495
<ListItem>
472496
<Para>
473-
A notify(l) command has been executed for arelation for
474-
whicha previous listen(l) command was executed. Notifications
497+
A notify(l) command has been executed for aname for which
498+
a previous listen(l) command was executed. Notifications
475499
may be sent at any time.
476500
</Para>
477501
</ListItem>
478502
</VarListEntry>
479503
</VariableList>
480504
</Para>
481505

506+
<Para>
507+
It may be worth pointing out that the names used in listen and notify
508+
commands need not have anything to do with names of relations (tables)
509+
in the SQL database. Notification names are simply arbitrarily chosen
510+
condition names.
511+
482512

483513
<Sect2>
484514
<Title>Cancelling Requests in Progress</Title>
485515

486516
<Para>
487517
During the processing of a query, the frontend may request cancellation of the
488-
query by sending a single byte of OOB (out-of-band) data. The contents of the
489-
data byte should be zero (although the backend does not currently check this).
490-
If the cancellation is effective, it results in the current command being
491-
terminated with an error message. Note that the backend makes no specific
492-
reply to the cancel request itself. If the cancel request is ineffective
493-
(say, because it arrived after processing was complete) then it will have
494-
no visible effect at all. Thus, the frontend must continue with its normal
495-
processing of query cycle responses after issuing a cancel request.
518+
query by sending an appropriate request to the postmaster. The cancel request
519+
is not sent directly to the backend for reasons of implementation efficiency:
520+
we don't want to have the backend constantly checking for new input from
521+
the frontend during query processing. Cancel requests should be relatively
522+
infrequent, so we make them slightly cumbersome in order to avoid a penalty
523+
in the normal case.
524+
525+
<Para>
526+
To issue a cancel request, the frontend opens a new connection to the
527+
postmaster and sends a CancelRequest message, rather than the StartupPacket
528+
message that would ordinarily be sent across a new connection. The postmaster
529+
will process this request and then close the connection. For security
530+
reasons, no direct reply is made to the cancel request message.
531+
532+
<Para>
533+
A CancelRequest message will be ignored unless it contains the same key data
534+
(PID and secret key) passed to the frontend during connection startup. If the
535+
request matches the PID and secret key for a currently executing backend, the
536+
postmaster signals the backend to abort processing of the current query.
537+
538+
<Para>
539+
The cancellation signal may or may not have any effect --- for example, if it
540+
arrives after the backend has finished processing the query, then it will have
541+
no effect. If the cancellation is effective, it results in the current
542+
command being terminated early with an error message.
543+
544+
<Para>
545+
The upshot of all this is that for reasons of both security and efficiency,
546+
the frontend has no direct way to tell whether a cancel request has succeeded.
547+
It must continue to wait for the backend to respond to the query. Issuing a
548+
cancel simply improves the odds that the current query will finish soon,
549+
and improves the odds that it will fail with an error message instead of
550+
succeeding.
551+
552+
<Para>
553+
Since the cancel request is sent to the postmaster and not across the
554+
regular frontend/backend communication link, it is possible for the cancel
555+
request to be issued by any process, not just the frontend whose query is
556+
to be canceled. This may have some benefits of flexibility in building
557+
multiple-process applications. It also introduces a security risk, in that
558+
unauthorized persons might try to cancel queries. The security risk is
559+
addressed by requiring a dynamically generated secret key to be supplied
560+
in cancel requests.
496561

497562

498563
<Sect2>
499564
<Title>Termination</Title>
500565

501566
<Para>
502-
The frontend sends a Terminate message and immediately closes the connection.
503-
On receipt of the message, the backend immediately closes the connection and
504-
terminates.
567+
The normal, graceful termination procedure is that the frontend sends a
568+
Terminate message and immediately closes the connection. On receipt of the
569+
message, the backend immediately closes the connection and terminates.
570+
571+
<Para>
572+
An ungraceful termination may occur due to software failure (i.e., core dump)
573+
at either end. If either frontend or backend sees an unexpected closure of
574+
the connection, it should clean up and terminate. The frontend has the option
575+
of launching a new backend by recontacting the postmaster, if it doesn't want
576+
to terminate itself.
505577

506578

507579
<Sect1>
@@ -824,6 +896,52 @@ AuthenticationEncryptedPassword (B)
824896
</VarListEntry>
825897
</VariableList>
826898

899+
</Para>
900+
</ListItem>
901+
</VarListEntry>
902+
<VarListEntry>
903+
<Term>
904+
BackendKeyData (B)
905+
</Term>
906+
<ListItem>
907+
<Para>
908+
909+
<VariableList>
910+
<VarListEntry>
911+
<Term>
912+
Byte1('K')
913+
</Term>
914+
<ListItem>
915+
<Para>
916+
Identifies the message as cancellation key data.
917+
The frontend must save these values if it wishes to be
918+
able to issue CancelRequest messages later.
919+
</Para>
920+
</ListItem>
921+
</VarListEntry>
922+
<VarListEntry>
923+
<Term>
924+
Int32
925+
</Term>
926+
<ListItem>
927+
<Para>
928+
The process ID of this backend.
929+
</Para>
930+
</ListItem>
931+
</VarListEntry>
932+
<VarListEntry>
933+
<Term>
934+
Int32
935+
</Term>
936+
<ListItem>
937+
<Para>
938+
The secret key of this backend.
939+
</Para>
940+
</ListItem>
941+
</VarListEntry>
942+
</VariableList>
943+
944+
827945
</Para>
828946
</ListItem>
829947
</VarListEntry>
@@ -892,6 +1010,63 @@ BinaryRow (B)
8921010
</VarListEntry>
8931011
</VariableList>
8941012

1013+
</Para>
1014+
</ListItem>
1015+
</VarListEntry>
1016+
<VarListEntry>
1017+
<Term>
1018+
CancelRequest (F)
1019+
</Term>
1020+
<ListItem>
1021+
<Para>
1022+
1023+
<VariableList>
1024+
<VarListEntry>
1025+
<Term>
1026+
Int32(16)
1027+
</Term>
1028+
<ListItem>
1029+
<Para>
1030+
The size of the packet in bytes.
1031+
</Para>
1032+
</ListItem>
1033+
</VarListEntry>
1034+
<VarListEntry>
1035+
<Term>
1036+
Int32(80877102)
1037+
</Term>
1038+
<ListItem>
1039+
<Para>
1040+
The cancel request code. The value is chosen to contain
1041+
"1234" in the most significant 16 bits, and "5678" in the
1042+
least 16 significant bits. (To avoid confusion, this code
1043+
must not be the same as any protocol version number.)
1044+
</Para>
1045+
</ListItem>
1046+
</VarListEntry>
1047+
<VarListEntry>
1048+
<Term>
1049+
Int32
1050+
</Term>
1051+
<ListItem>
1052+
<Para>
1053+
The process ID of the target backend.
1054+
</Para>
1055+
</ListItem>
1056+
</VarListEntry>
1057+
<VarListEntry>
1058+
<Term>
1059+
Int32
1060+
</Term>
1061+
<ListItem>
1062+
<Para>
1063+
The secret key for the target backend.
1064+
</Para>
1065+
</ListItem>
1066+
</VarListEntry>
1067+
</VariableList>
1068+
1069+
8951070
</Para>
8961071
</ListItem>
8971072
</VarListEntry>
@@ -1092,31 +1267,6 @@ EncryptedPasswordPacket (F)
10921267
</VariableList>
10931268

10941269

1095-
</Para>
1096-
</ListItem>
1097-
</VarListEntry>
1098-
<VarListEntry>
1099-
<Term>
1100-
ReadyForQuery (B)
1101-
</Term>
1102-
<ListItem>
1103-
<Para>
1104-
1105-
<VariableList>
1106-
<VarListEntry>
1107-
<Term>
1108-
Byte1('Z')
1109-
</Term>
1110-
<ListItem>
1111-
<Para>
1112-
Identifies the message type. ReadyForQuery is sent
1113-
whenever the backend is ready for a new query cycle.
1114-
</Para>
1115-
</ListItem>
1116-
</VarListEntry>
1117-
</VariableList>
1118-
1119-
11201270
</Para>
11211271
</ListItem>
11221272
</VarListEntry>
@@ -1449,6 +1599,31 @@ Query (F)
14491599
</VariableList>
14501600

14511601

1602+
</Para>
1603+
</ListItem>
1604+
</VarListEntry>
1605+
<VarListEntry>
1606+
<Term>
1607+
ReadyForQuery (B)
1608+
</Term>
1609+
<ListItem>
1610+
<Para>
1611+
1612+
<VariableList>
1613+
<VarListEntry>
1614+
<Term>
1615+
Byte1('Z')
1616+
</Term>
1617+
<ListItem>
1618+
<Para>
1619+
Identifies the message type. ReadyForQuery is sent
1620+
whenever the backend is ready for a new query cycle.
1621+
</Para>
1622+
</ListItem>
1623+
</VarListEntry>
1624+
</VariableList>
1625+
1626+
14521627
</Para>
14531628
</ListItem>
14541629
</VarListEntry>

‎src/backend/commands/async.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.34 1998/06/27 04:53:29 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.35 1998/07/09 03:28:44 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,11 +21,11 @@
2121
* 2.a If the process is the same as the backend process that issued
2222
* notification (we are notifying something that we are listening),
2323
* signal the corresponding frontend over the comm channel.
24-
* 2.b For all other listening processes, we send kill(2) to wake up
24+
* 2.b For all other listening processes, we send kill(SIGUSR2) to wake up
2525
* the listening backend.
26-
* 3. Upon receiving a kill(2) signal from another backend process notifying
27-
* that one of the relation that we are listening is being notified,
28-
* we can be in either of two following states:
26+
* 3. Upon receiving a kill(SIGUSR2) signal from another backend process
27+
*notifyingthat one of the relation that we are listening is being
28+
*notified,we can be in either of two following states:
2929
* 3.a We are sleeping, wake up and signal our frontend.
3030
* 3.b We are in middle of another transaction, wait until the end of
3131
* of the current transaction and signal our frontend.
@@ -46,7 +46,7 @@
4646
* (which takes place after commit) to all listeners on this relation.
4747
*
4848
* 3. Async. notification results in all backends listening on relation
49-
* to be woken up, by a process signal kill(2), with name of relation
49+
* to be woken up, by a process signal kill(SIGUSR2), with name of relation
5050
* passed in shared memory.
5151
*
5252
* 4. Each backend notifies its respective frontend over the comm

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp