mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
updates for new startup sequence, some reformatting
This commit is contained in:
parent
9e39ffe4cd
commit
adf1c52ce6
@ -1,247 +1,217 @@
|
||||
<Chapter Id="protocol">
|
||||
<DocInfo>
|
||||
<Author>
|
||||
<FirstName>Phil</FirstName>
|
||||
<Surname>Thompson</Surname>
|
||||
</Author>
|
||||
<Date>1998-08-08</Date>
|
||||
</DocInfo>
|
||||
<Title>Frontend/Backend Protocol</Title>
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.18 2001/06/22 23:27:48 petere Exp $ -->
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
<chapter id="protocol">
|
||||
<title>Frontend/Backend Protocol</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Written by Phil Thompson (<email>phil@river-bank.demon.co.uk</email>).
|
||||
Updates for protocol 2.0 by Tom Lane (<email>tgl@sss.pgh.pa.us</email>).
|
||||
</Para>
|
||||
</Note>
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
<application>PostgreSQL</application> uses a message-based protocol
|
||||
for communication between frontends and backends. The protocol is
|
||||
implemented over <acronym>TCP/IP</acronym> and also on Unix domain
|
||||
sockets. <productname>PostgreSQL</productname> 6.3 introduced
|
||||
version numbers into the protocol. This was done in such a way as
|
||||
to still allow connections from earlier versions of frontends, but
|
||||
this document does not cover the protocol used by those earlier
|
||||
versions.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> uses a message-based protocol for communication between frontends
|
||||
and backends. The protocol is implemented over <Acronym>TCP/IP</Acronym> and also on Unix sockets.
|
||||
<ProductName>Postgres</ProductName> 6.3 introduced version numbers into the protocol.
|
||||
This was done in such
|
||||
a way as to still allow connections from earlier versions of frontends, but
|
||||
this document does not cover the protocol used by those earlier versions.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
<para>
|
||||
This document describes version 2.0 of the protocol, implemented in
|
||||
<ProductName>Postgres</ProductName> 6.4 and later.
|
||||
<application>PostgreSQL</application> 6.4 and later.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Higher level features built on this protocol (for example, how <FileName>libpq</FileName> passes
|
||||
certain environment variables after the connection is established)
|
||||
are covered elsewhere.
|
||||
<para>
|
||||
Higher level features built on this protocol (for example, how
|
||||
<application>libpq</application> passes certain environment
|
||||
variables after the connection is established) are covered
|
||||
elsewhere.
|
||||
</para>
|
||||
|
||||
<Sect1 id="protocol-overview">
|
||||
<Title>Overview</Title>
|
||||
<sect1 id="protocol-overview">
|
||||
<title>Overview</title>
|
||||
|
||||
<Para>
|
||||
The three major components are the frontend (running on the client) and the
|
||||
postmaster and backend (running on the server). The postmaster and backend
|
||||
have different roles but may be implemented by the same executable.
|
||||
<para>
|
||||
A frontend opens a connection to the server and sends a start-up
|
||||
packet. This includes the names of the user and the database the
|
||||
user wants to connect to. The server then uses this, and the
|
||||
information in the <filename>pg_hba.conf</filename> file to
|
||||
determine what further authentication information it requires the
|
||||
frontend to send (if any) and responds to the frontend accordingly.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
A frontend sends a start-up packet to the postmaster. This includes the names
|
||||
of the user and the database the user wants to connect to. The postmaster then
|
||||
uses this, and the information in the <filename>pg_hba.conf</filename>
|
||||
file
|
||||
to determine what
|
||||
further authentication information it requires the frontend to send (if any)
|
||||
and responds to the frontend accordingly.
|
||||
<para>
|
||||
The frontend then sends any required authentication information.
|
||||
Once the server validates this it responds to the frontend that it
|
||||
is authenticated and sends a message indicating successful start-up
|
||||
(normal case) or failure (for example, an invalid database name).
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
The frontend then sends any required authentication information. Once the
|
||||
postmaster validates this it responds to the frontend that it is authenticated
|
||||
and hands over the connection to a backend. The backend then sends a message
|
||||
indicating successful start-up (normal case) or failure (for example, an
|
||||
invalid database name).
|
||||
<para>
|
||||
In order to serve multiple clients efficiently, the server would
|
||||
normally create a new child process to handle each incoming
|
||||
connection. However, this is not required. In the current
|
||||
implementation, a new child process is created immediately after an
|
||||
incoming connection is detected. In earlier versions of PostgreSQL
|
||||
(7.1 and earlier), the child process was created after sending the
|
||||
authentication confirmation message.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Subsequent communications are query and result packets exchanged between the
|
||||
frontend and the backend. The postmaster takes no further part in ordinary
|
||||
query/result communication. (However, the postmaster is involved when the
|
||||
frontend wishes to cancel a query currently being executed by its backend.
|
||||
Further details about that appear below.)
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
<para>
|
||||
When the frontend wishes to disconnect it sends an appropriate packet and
|
||||
closes the connection without waiting for a response for the backend.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Packets are sent as a data stream. The first byte determines what should be
|
||||
expected in the rest of the packet. The exception is packets sent from a
|
||||
frontend to the postmaster, which comprise a packet length then the packet
|
||||
itself. The difference is historical.
|
||||
<para>
|
||||
Packets are sent as a data stream. The first byte determines what
|
||||
should be expected in the rest of the packet. The exceptions are
|
||||
packets sent as part of the startup and authentication exchange,
|
||||
which comprise a packet length followed by the packet itself. The
|
||||
difference is historical.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<Sect1 id="protocol-protocol">
|
||||
<Title>Protocol</Title>
|
||||
<sect1 id="protocol-protocol">
|
||||
<title>Protocol</title>
|
||||
|
||||
<Para>
|
||||
This section describes the message flow. There are four different types of
|
||||
flows depending on the state of the connection:
|
||||
start-up, query, function call, and termination.
|
||||
There are also special provisions for notification responses and command
|
||||
cancellation, which can occur at any time after the start-up phase.
|
||||
<para>
|
||||
This section describes the message flow. There are four different
|
||||
types of flows depending on the state of the connection: start-up,
|
||||
query, function call, and termination. There are also special
|
||||
provisions for notification responses and command cancellation,
|
||||
which can occur at any time after the start-up phase.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Start-up</Title>
|
||||
|
||||
<Sect2>
|
||||
<Title>Start-up</Title>
|
||||
<para>
|
||||
Initially, the frontend sends a StartupPacket. The server uses
|
||||
this info and the contents of the <filename>pg_hba.conf</filename>
|
||||
file to determine what authentication method the frontend must
|
||||
use. The server then responds with one of the following messages:
|
||||
|
||||
<Para>
|
||||
Start-up is divided into an authentication phase and a backend start-up phase.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>ErrorResponse</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The server then immediately closes the connection.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<Para>
|
||||
Initially, the frontend sends a StartupPacket. The postmaster uses this info
|
||||
and the contents of the pg_hba.conf file to determine what authentication
|
||||
method the frontend must use. The postmaster then responds with one of the
|
||||
following messages:
|
||||
<varlistentry>
|
||||
<term>AuthenticationOk</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The authentication exchange is completed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<Para>
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ErrorResponse
|
||||
</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The postmaster then immediately closes the connection.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
AuthenticationOk
|
||||
</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The postmaster then hands over to the backend. The postmaster
|
||||
takes no further part in the communication.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
AuthenticationKerberosV4
|
||||
</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<varlistentry>
|
||||
<term>AuthenticationKerberosV4</Term>
|
||||
<listitem>
|
||||
<para>
|
||||
The frontend must then take part in a Kerberos V4
|
||||
authentication dialog (not described here) with the postmaster.
|
||||
If this is successful, the postmaster responds with an
|
||||
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
AuthenticationKerberosV5
|
||||
</Term>
|
||||
authentication dialog (not described here, part of the
|
||||
Kerberos specification) with the server. If this is
|
||||
successful, the server responds with an AuthenticationOk,
|
||||
otherwise it responds with an ErrorResponse.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<Term>AuthenticationKerberosV5</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The frontend must then take part in a Kerberos V5
|
||||
authentication dialog (not described here) with the postmaster.
|
||||
If this is successful, the postmaster responds with an
|
||||
authentication dialog (not described here, part of the
|
||||
Kerberos specification) with the server. If this is
|
||||
successful, the server responds with an AuthenticationOk,
|
||||
otherwise it responds with an ErrorResponse.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>AuthenticationUnencryptedPassword</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The frontend must then send an UnencryptedPasswordPacket. If
|
||||
this is the correct password, the server responds with an
|
||||
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
AuthenticationUnencryptedPassword
|
||||
</Term>
|
||||
<Term>AuthenticationEncryptedPassword</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The frontend must then send an UnencryptedPasswordPacket.
|
||||
If this is the correct password, the postmaster responds with
|
||||
an AuthenticationOk, otherwise it responds with an
|
||||
ErrorResponse.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
AuthenticationEncryptedPassword
|
||||
</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The frontend must then send an EncryptedPasswordPacket.
|
||||
If this is the correct password, the postmaster responds with
|
||||
an AuthenticationOk, otherwise it responds with an
|
||||
ErrorResponse.
|
||||
The frontend must then send an EncryptedPasswordPacket. If
|
||||
this is the correct password, the server responds with an
|
||||
AuthenticationOk, otherwise it responds with an ErrorResponse.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
</VariableList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If the frontend does not support the authentication method requested by the
|
||||
postmaster, then it should immediately close the connection.
|
||||
<para>
|
||||
If the frontend does not support the authentication method
|
||||
requested by the server, then it should immediately close the
|
||||
connection.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
After sending AuthenticationOk, the postmaster attempts to launch a backend
|
||||
process. Since this might fail, or the backend might encounter a failure
|
||||
during start-up, the frontend must wait for the backend to acknowledge
|
||||
successful start-up. The frontend should send no messages at this point.
|
||||
The possible messages from the backend during this phase are:
|
||||
<para>
|
||||
After having received AuthenticationOk, the frontend should wait
|
||||
for further messages from the server. The possible messages from
|
||||
the backend in this phase are:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
BackendKeyData
|
||||
</Term>
|
||||
<Term>BackendKeyData</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This message is issued after successful backend start-up.
|
||||
It provides secret-key data that the frontend must save
|
||||
if it wants to be able to issue cancel requests later.
|
||||
This message provides secret-key data that the frontend must
|
||||
save if it wants to be able to issue cancel requests later.
|
||||
The frontend should not respond to this message, but should
|
||||
continue listening for a ReadyForQuery message.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ReadyForQuery
|
||||
</Term>
|
||||
<Term>ReadyForQuery</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Backend start-up is successful. The frontend may now issue
|
||||
query or function call messages.
|
||||
Start-up is completed. The frontend may now issue query or
|
||||
function call messages.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ErrorResponse
|
||||
</Term>
|
||||
<Term>ErrorResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Backend start-up failed. The connection is closed after
|
||||
sending this message.
|
||||
Start-up failed. The connection is closed after sending this
|
||||
message.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
NoticeResponse
|
||||
</Term>
|
||||
<Term>NoticeResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A warning message has been issued. The frontend should
|
||||
@ -253,12 +223,13 @@ The possible messages from the backend during this phase are:
|
||||
</VariableList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The ReadyForQuery message is the same one that the backend will issue after
|
||||
each query cycle. Depending on the coding needs of the frontend, it is
|
||||
reasonable to consider ReadyForQuery as starting a query cycle (and then
|
||||
BackendKeyData indicates successful conclusion of the start-up phase),
|
||||
or to consider ReadyForQuery as ending the start-up phase and each subsequent
|
||||
<para>
|
||||
The ReadyForQuery message is the same one that the backend will
|
||||
issue after each query cycle. Depending on the coding needs of
|
||||
the frontend, it is reasonable to consider ReadyForQuery as
|
||||
starting a query cycle (and then BackendKeyData indicates
|
||||
successful conclusion of the start-up phase), or to consider
|
||||
ReadyForQuery as ending the start-up phase and each subsequent
|
||||
query cycle.
|
||||
</para>
|
||||
</sect2>
|
||||
@ -267,11 +238,12 @@ query cycle.
|
||||
<Title>Query</Title>
|
||||
|
||||
<Para>
|
||||
A Query cycle is initiated by the frontend sending a Query message to the
|
||||
backend. The backend then sends one or more response messages depending
|
||||
on the contents of the query command string, and finally a ReadyForQuery
|
||||
response message. ReadyForQuery informs the frontend that it may safely
|
||||
send a new query or function call.
|
||||
A Query cycle is initiated by the frontend sending a Query message
|
||||
to the backend. The backend then sends one or more response
|
||||
messages depending on the contents of the query command string,
|
||||
and finally a ReadyForQuery response message. ReadyForQuery
|
||||
informs the frontend that it may safely send a new query or
|
||||
function call.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
@ -279,84 +251,88 @@ The possible response messages from the backend are:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
CompletedResponse
|
||||
</Term>
|
||||
<Term>CompletedResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An SQL command completed normally.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
CopyInResponse
|
||||
</Term>
|
||||
<Term>CopyInResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The backend is ready to copy data from the frontend to a
|
||||
relation. The frontend should then send a CopyDataRows
|
||||
message. The backend will then respond with a
|
||||
CompletedResponse message with a tag of "COPY".
|
||||
table. The frontend should then send a CopyDataRows message.
|
||||
The backend will then respond with a CompletedResponse message
|
||||
with a tag of <literal>COPY</literal>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
CopyOutResponse
|
||||
</Term>
|
||||
<Term>CopyOutResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The backend is ready to copy data from a relation to the
|
||||
The backend is ready to copy data from a table to the
|
||||
frontend. It then sends a CopyDataRows message, and then a
|
||||
CompletedResponse message with a tag of "COPY".
|
||||
CompletedResponse message with a tag of <literal>COPY</literal>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
CursorResponse
|
||||
</Term>
|
||||
<Term>CursorResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The query was either an insert(l), delete(l), update(l),
|
||||
fetch(l) or a select(l) command.
|
||||
If the transaction has been
|
||||
aborted then the backend sends a CompletedResponse message with
|
||||
a tag of "*ABORT STATE*". Otherwise the following responses
|
||||
are sent.
|
||||
The query was either an <literal>INSERT</literal>,
|
||||
<literal>UPDATE</literal>, <literal>DELETE</literal>,
|
||||
<literal>FETCH</literal>, or a <literal>SELECT</literal>
|
||||
command. If the transaction has been aborted then the backend
|
||||
sends a CompletedResponse message with a tag of <literal>*ABORT
|
||||
STATE*</literal>. Otherwise the following responses are sent.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For an insert(l) command, the backend then sends a
|
||||
CompletedResponse message with a tag of "INSERT <Replaceable>oid</Replaceable> <Replaceable>rows</Replaceable>"
|
||||
where <Replaceable>rows</Replaceable> is the number of rows inserted, and <Replaceable>oid</Replaceable> is the
|
||||
object ID of the inserted row if <Replaceable>rows</Replaceable> is 1, otherwise <Replaceable>oid</Replaceable>
|
||||
is 0.
|
||||
For an <literal>INSERT</literal> command, the backend then
|
||||
sends a CompletedResponse message with a tag of
|
||||
<literal>INSERT <replaceable>oid</replaceable>
|
||||
<replaceable>rows</replaceable></literal>, where
|
||||
<replaceable>rows</replaceable> is the number of rows
|
||||
inserted, and <replaceable>oid</replaceable> is the object ID
|
||||
of the inserted row if <Replaceable>rows</Replaceable> is 1,
|
||||
otherwise <Replaceable>oid</Replaceable> is 0.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For a delete(l) command, the backend then sends a
|
||||
CompletedResponse message with a tag of "DELETE <Replaceable>rows</Replaceable>" where
|
||||
For a <literal>DELETE</literal> command, the backend then
|
||||
sends a CompletedResponse message with a tag of <literal>DELETE
|
||||
<Replaceable>rows</Replaceable></literal> where
|
||||
<Replaceable>rows</Replaceable> is the number of rows deleted.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For an update(l) command, the backend then sends a
|
||||
CompletedResponse message with a tag of "UPDATE <Replaceable>rows</Replaceable>" where
|
||||
<Replaceable>rows</Replaceable> is the number of rows deleted.
|
||||
For an <literal>UPDATE</literal> command, the backend then
|
||||
sends a CompletedResponse message with a tag of <literal>UPDATE
|
||||
<Replaceable>rows</Replaceable></literal> where
|
||||
<Replaceable>rows</Replaceable> is the number of rows affected
|
||||
by the update.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For a fetch(l) or select(l) command, the backend sends a
|
||||
RowDescription message. This is then followed by an AsciiRow
|
||||
or BinaryRow message (depending on whether a binary cursor was
|
||||
specified) for each row being returned to the frontend.
|
||||
Finally, the backend sends a CompletedResponse message with a
|
||||
tag of "SELECT".
|
||||
For a <literal>FETCH</literal> or <literal>SELECT</literal>
|
||||
command, the backend sends a RowDescription message. This is
|
||||
then followed by an AsciiRow or BinaryRow message (depending
|
||||
on whether a binary cursor was specified) for each row being
|
||||
returned to the frontend. Finally, the backend sends a
|
||||
CompletedResponse message with a tag of <literal>SELECT</literal>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
EmptyQueryResponse
|
||||
</Term>
|
||||
<Term>EmptyQueryResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An empty query string was recognized. (The need to specially
|
||||
@ -364,35 +340,32 @@ The possible response messages from the backend are:
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ErrorResponse
|
||||
</Term>
|
||||
<Term>ErrorResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An error has occurred.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ReadyForQuery
|
||||
</Term>
|
||||
<Term>ReadyForQuery</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Processing of the query string is complete. A separate
|
||||
message is sent to indicate this because the query string
|
||||
may contain multiple SQL commands. (CompletedResponse marks
|
||||
the end of processing one SQL command, not the whole string.)
|
||||
message is sent to indicate this because the query string may
|
||||
contain multiple SQL commands. (CompletedResponse marks the
|
||||
end of processing one SQL command, not the whole string.)
|
||||
ReadyForQuery will always be sent, whether processing
|
||||
terminates successfully or with an error.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
NoticeResponse
|
||||
</Term>
|
||||
<Term>NoticeResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A warning message has been issued in relation to the query.
|
||||
@ -401,26 +374,30 @@ The possible response messages from the backend are:
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
</VariableList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
A frontend must be prepared to accept ErrorResponse and NoticeResponse
|
||||
messages whenever it is expecting any other type of message.
|
||||
<para>
|
||||
A frontend must be prepared to accept ErrorResponse and
|
||||
NoticeResponse messages whenever it is expecting any other type of
|
||||
message.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Actually, it is possible for NoticeResponse to arrive even when the frontend
|
||||
is not expecting any kind of message, that is, the backend is nominally idle.
|
||||
(In particular, the backend can be commanded to terminate by its postmaster.
|
||||
In that case it will send a NoticeResponse before closing the connection.)
|
||||
It is recommended that the frontend check for such asynchronous notices just
|
||||
before issuing any new command.
|
||||
Actually, it is possible for NoticeResponse to arrive even when
|
||||
the frontend is not expecting any kind of message, that is, the
|
||||
backend is nominally idle. (In particular, the backend can be
|
||||
commanded to terminate by its parent process. In that case it will
|
||||
send a NoticeResponse before closing the connection.) It is
|
||||
recommended that the frontend check for such asynchronous notices
|
||||
just before issuing any new command.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Also, if the frontend issues any listen(l) commands then it must be prepared
|
||||
to accept NotificationResponse messages at any time; see below.
|
||||
Also, if the frontend issues any <literal>LISTEN</literal>
|
||||
commands then it must be prepared to accept NotificationResponse
|
||||
messages at any time; see below.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -428,11 +405,12 @@ to accept NotificationResponse messages at any time; see below.
|
||||
<Title>Function Call</Title>
|
||||
|
||||
<Para>
|
||||
A Function Call cycle is initiated by the frontend sending a FunctionCall
|
||||
message to the backend. The backend then sends one or more response messages
|
||||
depending on the results of the function call, and finally a ReadyForQuery
|
||||
response message. ReadyForQuery informs the frontend that it may safely send
|
||||
a new query or function call.
|
||||
A Function Call cycle is initiated by the frontend sending a
|
||||
FunctionCall message to the backend. The backend then sends one
|
||||
or more response messages depending on the results of the function
|
||||
call, and finally a ReadyForQuery response message. ReadyForQuery
|
||||
informs the frontend that it may safely send a new query or
|
||||
function call.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
@ -440,108 +418,103 @@ The possible response messages from the backend are:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ErrorResponse
|
||||
</Term>
|
||||
<Term>ErrorResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An error has occurred.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
FunctionResultResponse
|
||||
</Term>
|
||||
<Term>FunctionResultResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The function call was executed and returned a result.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
FunctionVoidResponse
|
||||
</Term>
|
||||
<Term>FunctionVoidResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The function call was executed and returned no result.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
ReadyForQuery
|
||||
</Term>
|
||||
<Term>ReadyForQuery</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Processing of the function call is complete.
|
||||
ReadyForQuery will always be sent, whether processing
|
||||
terminates successfully or with an error.
|
||||
Processing of the function call is complete. ReadyForQuery
|
||||
will always be sent, whether processing terminates
|
||||
successfully or with an error.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
NoticeResponse
|
||||
</Term>
|
||||
<Term>NoticeResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A warning message has been issued in relation to the function
|
||||
call.
|
||||
Notices are in addition to other responses, i.e., the backend
|
||||
will continue processing the command.
|
||||
call. Notices are in addition to other responses, i.e., the
|
||||
backend will continue processing the command.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
A frontend must be prepared to accept ErrorResponse and NoticeResponse
|
||||
messages whenever it is expecting any other type of message. Also,
|
||||
if it issues any listen(l) commands then it must be prepared to accept
|
||||
NotificationResponse messages at any time; see below.
|
||||
<para>
|
||||
A frontend must be prepared to accept ErrorResponse and
|
||||
NoticeResponse messages whenever it is expecting any other type of
|
||||
message. Also, if it issues any <literal>LISTEN</literal>
|
||||
commands then it must be prepared to accept NotificationResponse
|
||||
messages at any time; see below.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Notification Responses</Title>
|
||||
<sect2>
|
||||
<title>Notification Responses</title>
|
||||
|
||||
<Para>
|
||||
If a frontend issues a listen(l) command, then the backend will send a
|
||||
NotificationResponse message (not to be confused with NoticeResponse!)
|
||||
whenever a notify(l) command is executed for the same notification name.
|
||||
If a frontend issues a <literal>LISTEN</literal> command, then the
|
||||
backend will send a NotificationResponse message (not to be
|
||||
confused with NoticeResponse!) whenever a
|
||||
<literal>NOTIFY</literal> command is executed for the same
|
||||
notification name.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Notification responses are permitted at any point in the protocol (after
|
||||
start-up), except within another backend message. Thus, the frontend
|
||||
must be prepared to recognize a NotificationResponse message whenever it is
|
||||
expecting any message. Indeed, it should be able to handle
|
||||
NotificationResponse messages even when it is not engaged in a query.
|
||||
<para>
|
||||
Notification responses are permitted at any point in the protocol
|
||||
(after start-up), except within another backend message. Thus,
|
||||
the frontend must be prepared to recognize a NotificationResponse
|
||||
message whenever it is expecting any message. Indeed, it should
|
||||
be able to handle NotificationResponse messages even when it is
|
||||
not engaged in a query.
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>
|
||||
NotificationResponse
|
||||
</Term>
|
||||
<Term>NotificationResponse</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A notify(l) command has been executed for a name for which
|
||||
a previous listen(l) command was executed. Notifications
|
||||
may be sent at any time.
|
||||
A <literal>NOTIFY</literal> command has been executed for a
|
||||
name for which a previous <literal>LISTEN</literal> command
|
||||
was executed. Notifications may be sent at any time.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
It may be worth pointing out that the names used in listen and notify
|
||||
commands need not have anything to do with names of relations (tables)
|
||||
in the SQL database. Notification names are simply arbitrarily chosen
|
||||
condition names.
|
||||
<para>
|
||||
It may be worth pointing out that the names used in listen and
|
||||
notify commands need not have anything to do with names of
|
||||
relations (tables) in the SQL database. Notification names are
|
||||
simply arbitrarily chosen condition names.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -549,55 +522,63 @@ condition names.
|
||||
<Title>Cancelling Requests in Progress</Title>
|
||||
|
||||
<Para>
|
||||
During the processing of a query, the frontend may request cancellation of the
|
||||
query by sending an appropriate request to the postmaster. The cancel request
|
||||
is not sent directly to the backend for reasons of implementation efficiency:
|
||||
we don't want to have the backend constantly checking for new input from
|
||||
the frontend during query processing. Cancel requests should be relatively
|
||||
infrequent, so we make them slightly cumbersome in order to avoid a penalty
|
||||
in the normal case.
|
||||
During the processing of a query, the frontend may request
|
||||
cancellation of the query. The cancel request is not sent
|
||||
directly on the open connection to the backend for reasons of
|
||||
implementation efficiency: we don't want to have the backend
|
||||
constantly checking for new input from the frontend during query
|
||||
processing. Cancel requests should be relatively infrequent, so
|
||||
we make them slightly cumbersome in order to avoid a penalty in
|
||||
the normal case.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
To issue a cancel request, the frontend opens a new connection to the
|
||||
postmaster and sends a CancelRequest message, rather than the StartupPacket
|
||||
message that would ordinarily be sent across a new connection. The postmaster
|
||||
will process this request and then close the connection. For security
|
||||
reasons, no direct reply is made to the cancel request message.
|
||||
To issue a cancel request, the frontend opens a new connection to
|
||||
the server and sends a CancelRequest message, rather than the
|
||||
StartupPacket message that would ordinarily be sent across a new
|
||||
connection. The server will process this request and then close
|
||||
the connection. For security reasons, no direct reply is made to
|
||||
the cancel request message.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
A CancelRequest message will be ignored unless it contains the same key data
|
||||
(PID and secret key) passed to the frontend during connection start-up. If the
|
||||
request matches the PID and secret key for a currently executing backend, the
|
||||
postmaster signals the backend to abort processing of the current query.
|
||||
A CancelRequest message will be ignored unless it contains the
|
||||
same key data (PID and secret key) passed to the frontend during
|
||||
connection start-up. If the request matches the PID and secret
|
||||
key for a currently executing backend, the processing of the
|
||||
current query is aborted. (In the existing implemenation, this is
|
||||
done by sending a special signal to the backend process that is
|
||||
processing the query.)
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
The cancellation signal may or may not have any effect --- for example, if it
|
||||
arrives after the backend has finished processing the query, then it will have
|
||||
no effect. If the cancellation is effective, it results in the current
|
||||
command being terminated early with an error message.
|
||||
The cancellation signal may or may not have any effect --- for
|
||||
example, if it arrives after the backend has finished processing
|
||||
the query, then it will have no effect. If the cancellation is
|
||||
effective, it results in the current command being terminated
|
||||
early with an error message.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
The upshot of all this is that for reasons of both security and efficiency,
|
||||
the frontend has no direct way to tell whether a cancel request has succeeded.
|
||||
It must continue to wait for the backend to respond to the query. Issuing a
|
||||
cancel simply improves the odds that the current query will finish soon,
|
||||
and improves the odds that it will fail with an error message instead of
|
||||
The upshot of all this is that for reasons of both security and
|
||||
efficiency, the frontend has no direct way to tell whether a
|
||||
cancel request has succeeded. It must continue to wait for the
|
||||
backend to respond to the query. Issuing a cancel simply improves
|
||||
the odds that the current query will finish soon, and improves the
|
||||
odds that it will fail with an error message instead of
|
||||
succeeding.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
Since the cancel request is sent to the postmaster and not across the
|
||||
regular frontend/backend communication link, it is possible for the cancel
|
||||
request to be issued by any process, not just the frontend whose query is
|
||||
to be canceled. This may have some benefits of flexibility in building
|
||||
multiple-process applications. It also introduces a security risk, in that
|
||||
unauthorized persons might try to cancel queries. The security risk is
|
||||
addressed by requiring a dynamically generated secret key to be supplied
|
||||
in cancel requests.
|
||||
Since the cancel request is sent across a new connection to the
|
||||
server and not across the regular frontend/backend communication
|
||||
link, it is possible for the cancel request to be issued by any
|
||||
process, not just the frontend whose query is to be canceled.
|
||||
This may have some benefits of flexibility in building
|
||||
multiple-process applications. It also introduces a security
|
||||
risk, in that unauthorized persons might try to cancel queries.
|
||||
The security risk is addressed by requiring a dynamically
|
||||
generated secret key to be supplied in cancel requests.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -605,17 +586,19 @@ in cancel requests.
|
||||
<Title>Termination</Title>
|
||||
|
||||
<Para>
|
||||
The normal, graceful termination procedure is that the frontend sends a
|
||||
Terminate message and immediately closes the connection. On receipt of the
|
||||
message, the backend immediately closes the connection and terminates.
|
||||
The normal, graceful termination procedure is that the frontend
|
||||
sends a Terminate message and immediately closes the connection.
|
||||
On receipt of the message, the backend immediately closes the
|
||||
connection and terminates.
|
||||
</para>
|
||||
|
||||
<Para>
|
||||
An ungraceful termination may occur due to software failure (i.e., core dump)
|
||||
at either end. If either frontend or backend sees an unexpected closure of
|
||||
the connection, it should clean up and terminate. The frontend has the option
|
||||
of launching a new backend by recontacting the postmaster, if it doesn't want
|
||||
to terminate itself.
|
||||
An ungraceful termination may occur due to software failure (i.e.,
|
||||
core dump) at either end. If either frontend or backend sees an
|
||||
unexpected closure of the connection, it should clean up and
|
||||
terminate. The frontend has the option of launching a new backend
|
||||
by recontacting the server if it doesn't want to terminate
|
||||
itself.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
@ -695,7 +678,7 @@ characters that don't fit into your fixed-size buffer.
|
||||
|
||||
<Para>
|
||||
This section describes the detailed format of each message. Each can be sent
|
||||
by either a frontend (F), a postmaster/backend (B), or both (F & B).
|
||||
by either a frontend (F), a backend (B), or both (F & B).
|
||||
</para>
|
||||
|
||||
<VariableList>
|
||||
@ -1815,7 +1798,7 @@ StartupPacket (F)
|
||||
<ListItem>
|
||||
<Para>
|
||||
Any additional command line arguments to be passed to the
|
||||
backend by the postmaster.
|
||||
backend child process by the server.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
Loading…
x
Reference in New Issue
Block a user