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