📄 protocol.sgml
字号:
<!-- $PostgreSQL: pgsql/doc/src/sgml/protocol.sgml,v 1.62 2005/08/14 22:19:49 petere Exp $ --><chapter id="protocol"> <title>Frontend/Backend Protocol</title> <para> <productname>PostgreSQL</productname> uses a message-based protocol for communication between frontends and backends (clients and servers). The protocol is supported over <acronym>TCP/IP</acronym> and also over Unix-domain sockets. Port number 5432 has been registered with IANA as the customary TCP port number for servers supporting this protocol, but in practice any non-privileged port number may be used. </para> <para> This document describes version 3.0 of the protocol, implemented in <productname>PostgreSQL</productname> 7.4 and later. For descriptions of the earlier protocol versions, see previous releases of the <productname>PostgreSQL</productname> documentation. A single server can support multiple protocol versions. The initial startup-request message tells the server which protocol version the client is attempting to use, and then the server follows that protocol if it is able. </para> <para> Higher level features built on this protocol (for example, how <application>libpq</application> passes certain environment variables when the connection is established) are covered elsewhere. </para> <para> In order to serve multiple clients efficiently, the server launches a new <quote>backend</> process for each client. In the current implementation, a new child process is created immediately after an incoming connection is detected. This is transparent to the protocol, however. For purposes of the protocol, the terms <quote>backend</> and <quote>server</> are interchangeable; likewise <quote>frontend</> and <quote>client</> are interchangeable. </para> <sect1 id="protocol-overview"> <title>Overview</title> <para> The protocol has separate phases for startup and normal operation. In the startup phase, the frontend opens a connection to the server and authenticates itself to the satisfaction of the server. (This might involve a single message, or multiple messages depending on the authentication method being used.) If all goes well, the server then sends status information to the frontend, and finally enters normal operation. Except for the initial startup-request message, this part of the protocol is driven by the server. </para> <para> During normal operation, the frontend sends queries and other commands to the backend, and the backend sends back query results and other responses. There are a few cases (such as <command>NOTIFY</>) wherein the backend will send unsolicited messages, but for the most part this portion of a session is driven by frontend requests. </para> <para> Termination of the session is normally by frontend choice, but can be forced by the backend in certain cases. In any case, when the backend closes the connection, it will roll back any open (incomplete) transaction before exiting. </para> <para> Within normal operation, SQL commands can be executed through either of two sub-protocols. In the <quote>simple query</> protocol, the frontend just sends a textual query string, which is parsed and immediately executed by the backend. In the <quote>extended query</> protocol, processing of queries is separated into multiple steps: parsing, binding of parameter values, and execution. This offers flexibility and performance benefits, at the cost of extra complexity. </para> <para> Normal operation has additional sub-protocols for special operations such as <command>COPY</>. </para> <sect2 id="protocol-message-concepts"> <title>Messaging Overview</title> <para> All communication is through a stream of messages. The first byte of a message identifies the message type, and the next four bytes specify the length of the rest of the message (this length count includes itself, but not the message-type byte). The remaining contents of the message are determined by the message type. For historical reasons, the very first message sent by the client (the startup message) has no initial message-type byte. </para> <para> To avoid losing synchronization with the message stream, both servers and clients typically read an entire message into a buffer (using the byte count) before attempting to process its contents. This allows easy recovery if an error is detected while processing the contents. In extreme situations (such as not having enough memory to buffer the message), the receiver may use the byte count to determine how much input to skip before it resumes reading messages. </para> <para> Conversely, both servers and clients must take care never to send an incomplete message. This is commonly done by marshaling the entire message in a buffer before beginning to send it. If a communications failure occurs partway through sending or receiving a message, the only sensible response is to abandon the connection, since there is little hope of recovering message-boundary synchronization. </para> </sect2> <sect2 id="protocol-query-concepts"> <title>Extended Query Overview</title> <para> In the extended-query protocol, execution of SQL commands is divided into multiple steps. The state retained between steps is represented by two types of objects: <firstterm>prepared statements</> and <firstterm>portals</>. A prepared statement represents the result of parsing, semantic analysis, and planning of a textual query string. A prepared statement is not necessarily ready to execute, because it may lack specific values for <firstterm>parameters</>. A portal represents a ready-to-execute or already-partially-executed statement, with any missing parameter values filled in. (For <command>SELECT</> statements, a portal is equivalent to an open cursor, but we choose to use a different term since cursors don't handle non-<command>SELECT</> statements.) </para> <para> The overall execution cycle consists of a <firstterm>parse</> step, which creates a prepared statement from a textual query string; a <firstterm>bind</> step, which creates a portal given a prepared statement and values for any needed parameters; and an <firstterm>execute</> step that runs a portal's query. In the case of a query that returns rows (<command>SELECT</>, <command>SHOW</>, etc), the execute step can be told to fetch only a limited number of rows, so that multiple execute steps may be needed to complete the operation. </para> <para> The backend can keep track of multiple prepared statements and portals (but note that these exist only within a session, and are never shared across sessions). Existing prepared statements and portals are referenced by names assigned when they were created. In addition, an <quote>unnamed</> prepared statement and portal exist. Although these behave largely the same as named objects, operations on them are optimized for the case of executing a query only once and then discarding it, whereas operations on named objects are optimized on the expectation of multiple uses. </para> </sect2> <sect2 id="protocol-format-codes"> <title>Formats and Format Codes</title> <para> Data of a particular data type might be transmitted in any of several different <firstterm>formats</>. As of <productname>PostgreSQL</> 7.4 the only supported formats are <quote>text</> and <quote>binary</>, but the protocol makes provision for future extensions. The desired format for any value is specified by a <firstterm>format code</>. Clients may specify a format code for each transmitted parameter value and for each column of a query result. Text has format code zero, binary has format code one, and all other format codes are reserved for future definition. </para> <para> The text representation of values is whatever strings are produced and accepted by the input/output conversion functions for the particular data type. In the transmitted representation, there is no trailing null character; the frontend must add one to received values if it wants to process them as C strings. (The text format does not allow embedded nulls, by the way.) </para> <para> Binary representations for integers use network byte order (most significant byte first). For other data types consult the documentation or source code to learn about the binary representation. Keep in mind that binary representations for complex data types may change across server versions; the text format is usually the more portable choice. </para> </sect2> </sect1> <sect1 id="protocol-flow"> <title>Message Flow</title> <para> This section describes the message flow and the semantics of each message type. (Details of the exact representation of each message appear in <xref linkend="protocol-message-formats">.) There are several different sub-protocols depending on the state of the connection: start-up, query, function call, <command>COPY</command>, and termination. There are also special provisions for asynchronous operations (including notification responses and command cancellation), which can occur at any time after the start-up phase. </para> <sect2> <title>Start-Up</title> <para> To begin a session, a frontend opens a connection to the server and sends a startup message. This message includes the names of the user and of the database the user wants to connect to; it also identifies the particular protocol version to be used. (Optionally, the startup message can include additional settings for run-time parameters.) The server then uses this information and the contents of its configuration files (such as <filename>pg_hba.conf</filename>) to determine whether the connection is provisionally acceptable, and what additional authentication is required (if any). </para> <para> The server then sends an appropriate authentication request message, to which the frontend must reply with an appropriate authentication response message (such as a password). In principle the authentication request/response cycle could require multiple iterations, but none of the present authentication methods use more than one request and response. In some methods, no response at all is needed from the frontend, and so no authentication request occurs. </para> <para> The authentication cycle ends with the server either rejecting the connection attempt (ErrorResponse), or sending AuthenticationOk. </para> <para> The possible messages from the server in this phase are: <variablelist> <varlistentry> <term>ErrorResponse</term> <listitem> <para> The connection attempt has been rejected. The server then immediately closes the connection. </para> </listitem> </varlistentry> <varlistentry> <term>AuthenticationOk</term> <listitem> <para> The authentication exchange is successfully completed. </para> </listitem> </varlistentry> <varlistentry> <term>AuthenticationKerberosV5</term> <listitem> <para> The frontend must now take part in a Kerberos V5 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>AuthenticationCleartextPassword</term> <listitem> <para> The frontend must now send a PasswordMessage containing the password in clear-text form. If this is the correct password, the server responds with an AuthenticationOk, otherwise it responds with an ErrorResponse. </para> </listitem> </varlistentry> <varlistentry> <term>AuthenticationCryptPassword</term> <listitem> <para> The frontend must now send a PasswordMessage containing the password encrypted via crypt(3), using the 2-character salt specified in the AuthenticationCryptPassword message. If this is the correct password, the server responds with an AuthenticationOk, otherwise it responds with an ErrorResponse. </para> </listitem> </varlistentry> <varlistentry> <term>AuthenticationMD5Password</term> <listitem> <para> The frontend must now send a PasswordMessage containing the password encrypted via MD5, using the 4-character salt specified in the AuthenticationMD5Password message. If this is the correct password, the server responds with an AuthenticationOk, otherwise it responds with an ErrorResponse. </para> </listitem> </varlistentry> <varlistentry> <term>AuthenticationSCMCredential</term> <listitem> <para> This response is only possible for local Unix-domain connections on platforms that support SCM credential messages. The frontend must issue an SCM credential message and then send a single data byte. (The contents of the data byte are uninteresting; it's only used to ensure that the server waits long enough to receive the credential message.) If the credential is acceptable, 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 server, then it should immediately close the connection. </para> <para> After having received AuthenticationOk, the frontend must wait for further messages from the server. In this phase a backend process is being started, and the frontend is just an interested bystander. It is still possible for the startup attempt to fail (ErrorResponse), but in the normal case the backend will send some ParameterStatus messages, BackendKeyData, and finally ReadyForQuery. </para> <para> During this phase the backend will attempt to apply any additional run-time parameter settings that were given in the startup message. If successful, these values become session defaults. An error causes ErrorResponse and exit. </para> <para> The possible messages from the backend in this phase are: <variablelist> <varlistentry> <term>BackendKeyData</term> <listitem> <para> 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>ParameterStatus</term> <listitem> <para> This message informs the frontend about the current (initial) setting of backend parameters, such as <xref linkend="guc-client-encoding"> or <xref linkend="guc-datestyle">. The frontend may ignore this message, or record the settings for its future use; see <xref linkend="protocol-async"> for more details. The frontend should not respond to this message, but should continue listening for a ReadyForQuery message. </para> </listitem> </varlistentry> <varlistentry> <term>ReadyForQuery</term> <listitem> <para> Start-up is completed. The frontend may now issue commands.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -