📄 protocol.sgml
字号:
<Term>ErrorResponse</Term> <ListItem> <Para> An error has occurred. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term>FunctionCallResponse</Term> <ListItem> <Para> The function call was completed and returned the result given in the message. (Note that the Function Call protocol can only handle a single scalar result, not a rowtype or set of results.) </Para> </ListItem> </VarListEntry> <VarListEntry> <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. </Para> </ListItem> </VarListEntry> <VarListEntry> <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. </Para> </ListItem> </VarListEntry> </VariableList> </Para> </sect2> <sect2 id="protocol-copy"> <title>COPY Operations</title> <para> The <command>COPY</> command allows high-speed bulk data transfer to or from the server. Copy-in and copy-out operations each switch the connection into a distinct sub-protocol, which lasts until the operation is completed. </para> <para> Copy-in mode (data transfer to the server) is initiated when the backend executes a <command>COPY FROM STDIN</> SQL statement. The backend sends a CopyInResponse message to the frontend. The frontend should then send zero or more CopyData messages, forming a stream of input data. (The message boundaries are not required to have anything to do with row boundaries, although that is often a reasonable choice.) The frontend can terminate the copy-in mode by sending either a CopyDone message (allowing successful termination) or a CopyFail message (which will cause the <command>COPY</> SQL statement to fail with an error). The backend then reverts to the command-processing mode it was in before the <command>COPY</> started, which will be either simple or extended query protocol. It will next send either CommandComplete (if successful) or ErrorResponse (if not). </para> <para> In the event of a backend-detected error during copy-in mode (including receipt of a CopyFail message), the backend will issue an ErrorResponse message. If the <command>COPY</> command was issued via an extended-query message, the backend will now discard frontend messages until a Sync message is received, then it will issue ReadyForQuery and return to normal processing. If the <command>COPY</> command was issued in a simple Query message, the rest of that message is discarded and ReadyForQuery is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail messages issued by the frontend will simply be dropped. </para> <para> The backend will ignore Flush and Sync messages received during copy-in mode. Receipt of any other non-copy message type constitutes an error that will abort the copy-in state as described above. (The exception for Flush and Sync is for the convenience of client libraries that always send Flush or Sync after an Execute message, without checking whether the command to be executed is a <command>COPY FROM STDIN</>.) </para> <para> Copy-out mode (data transfer from the server) is initiated when the backend executes a <command>COPY TO STDOUT</> SQL statement. The backend sends a CopyOutResponse message to the frontend, followed by zero or more CopyData messages (always one per row), followed by CopyDone. The backend then reverts to the command-processing mode it was in before the <command>COPY</> started, and sends CommandComplete. The frontend cannot abort the transfer (except by closing the connection or issuing a Cancel request), but it can discard unwanted CopyData and CopyDone messages. </para> <para> In the event of a backend-detected error during copy-out mode, the backend will issue an ErrorResponse message and revert to normal processing. The frontend should treat receipt of ErrorResponse (or indeed any message type other than CopyData or CopyDone) as terminating the copy-out mode. </para> <para> The CopyInResponse and CopyOutResponse messages include fields that inform the frontend of the number of columns per row and the format codes being used for each column. (As of the present implementation, all columns in a given <command>COPY</> operation will use the same format, but the message design does not assume this.) </para> </sect2> <sect2 id="protocol-async"> <title>Asynchronous Operations</title> <para> There are several cases in which the backend will send messages that are not specifically prompted by the frontend's command stream. Frontends must be prepared to deal with these messages at any time, even when not engaged in a query. At minimum, one should check for these cases before beginning to read a query response. </para> <para> It is possible for NoticeResponse messages to be generated due to outside activity; for example, if the database administrator commands a <quote>fast</> database shutdown, the backend will send a NoticeResponse indicating this fact before closing the connection. Accordingly, frontends should always be prepared to accept and display NoticeResponse messages, even when the connection is nominally idle. </para> <para> ParameterStatus messages will be generated whenever the active value changes for any of the parameters the backend believes the frontend should know about. Most commonly this occurs in response to a <command>SET</> SQL command executed by the frontend, and this case is effectively synchronous --- but it is also possible for parameter status changes to occur because the administrator changed a configuration file and then sent the <systemitem>SIGHUP</systemitem> signal to the postmaster. Also, if a SET command is rolled back, an appropriate ParameterStatus message will be generated to report the current effective value. </para> <para> At present there is a hard-wired set of parameters for which ParameterStatus will be generated: they are <literal>server_version</> (a pseudo-parameter that cannot change after startup); <literal>client_encoding</>, <literal>is_superuser</>, <literal>session_authorization</literal>, and <literal>DateStyle</>. This set might change in the future, or even become configurable. Accordingly, a frontend should simply ignore ParameterStatus for parameters that it does not understand or care about. </para> <para> If a frontend issues a <command>LISTEN</command> command, then the backend will send a NotificationResponse message (not to be confused with NoticeResponse!) whenever a <command>NOTIFY</command> command is executed for the same notification name. </para> <note> <para> At present, NotificationResponse can only be sent outside a transaction, and thus it will not occur in the middle of a command-response series, though it may occur just before ReadyForQuery. It is unwise to design frontend logic that assumes that, however. Good practice is to be able to accept NotificationResponse at any point in the protocol. </para> </note> </sect2> <Sect2> <Title>Cancelling Requests in Progress</Title> <Para> 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 server and sends a CancelRequest message, rather than the StartupMessage 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 processing of the current query is aborted. (In the existing implementation, 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. </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 succeeding. </para> <Para> 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> <Sect2> <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 this message, the backend closes the connection and terminates. </para> <para> In rare cases (such as an administrator-commanded database shutdown) the backend may disconnect without any frontend request to do so. In such cases the backend will attempt to send an error or notice message giving the reason for the disconnection before it closes the connection. </para> <para> Other termination scenarios arise from various failure cases, such as core dump at one end or the other, loss of the communications link, loss of message-boundary synchronization, etc. 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. Closing the connection is also advisable if an unrecognizable message type is received, since this probably indicates loss of message-boundary sync. </para> <para> For either normal or abnormal termination, any open transaction is rolled back, not committed. One should note however that if a frontend disconnects while a non-SELECT query is being processed, the backend will probably finish the query before noticing the disconnection. If the query is outside any transaction block (<command>BEGIN</> ... <command>COMMIT</> sequence) then its results may be committed before the disconnection is recognized. </para> </sect2> <Sect2> <Title>SSL Session Encryption</Title> <Para> If <productname>PostgreSQL</> was built with SSL support, frontend/backend communications can be encrypted using SSL. This provides communication security in environments where attackers might be able to capture the session traffic. </para> <para> To initiate an SSL-encrypted connection, the frontend initially sends an SSLRequest message rather than a StartupMessage. The server then responds with a single byte containing <literal>S</> or <literal>N</>, indicating that it is willing or unwilling to perform SSL, respectively. The frontend may close the connection at this point if it is dissatisfied with the response. To continue after <literal>S</>, perform an SSL startup handshake (not described here, part of the SSL specification) with the server. If this is successful, continue with sending the usual StartupMessage. In this case the StartupMessage and all subsequent data will be SSL-encrypted. To continue after <literal>N</>, send the usual StartupMessage and proceed without encryption. </para> <para> The frontend should also be prepared to handle an ErrorMessage response to SSLRequest from the server. This would only occur if the server predates the addition of SSL support to <productname>PostgreSQL</>. In this case the connection must be closed, but the frontend may choose to open a fresh connection and proceed without requesting SSL. </para> <para> An initial SSLRequest may also be used in a connection that is being opened to send a CancelRequest message. </para> <para> While the protocol itself does not provide a way for the server to force SSL encryption, the administrator may configure the server to reject unencrypted sessions as a byproduct of authentication checking. </para> </sect2> </sect1><Sect1 id="protocol-message-types"><Title>Message Data Types</Title><Para>This section describes the base data types used in messages.<VariableList><VarListEntry><Term> Int<Replaceable>n</Replaceable>(<Replaceable>i</Replaceable>)</Term><ListItem><Para> An <Replaceable>n</Replaceable>-bit integer in network byte order (most significant byte first). If <Replaceable>i</Replaceable> is specified it is the exact value that will appear, otherwise the value is variable. Eg. Int16, Int32(42).</Para></ListItem></VarListEntry><VarListEntry><Term> Int<Replaceable>n</Replaceable>[<Replaceable>k</Replaceable>]</Term><ListItem><Para> An array of <Replaceable>k</Replaceable> <Replaceable>n</Replaceable>-bit integers, each in network byte order. The array length <Replaceable>k</Replaceable> is always determined by an earlier field in the message. Eg. Int16[M].</Para></ListItem></VarListEntry><VarListEntry><Term> String(<Replaceable>s</Replaceable>)</Term><ListItem><Para> A null-terminated string (C-style string). There is no specific length limitation on strings. If <Replaceable>s</Replaceable> is specified it is the exact value that will appear, otherwise the value is variable. Eg. String, String("user").</Para> <Note><Para><Emphasis>There is no predefined limit</Emphasis> on the length of a stringthat can be returned by the backend. Good coding strategy for a frontendis to use an expandable buffer so that anything that fits in memory can beaccepted. If that's not feasible, read the full string and discard trailingcharacters that don't fit into your fixed-size buffer.</Para></Note></ListItem></VarListEntry><VarListEntry><Term> Byte<Replaceable>n</Replaceable>(<Replaceable>c</Replaceable>)</Term><ListItem><Para> Exactly <Replaceable>n</Replaceable> bytes. If the field width <Replaceable>n</Replaceable> is not a constant, it is always determinable from an earlier field in the message. If <Replaceable>c</Replaceable> is specified it is the exact value. Eg. Byte2, Byte1('\n').</Para></ListItem></VarListEntry></VariableList></Para></sect1><Sect1 id="protocol-message-formats"><Title>Message Formats</Title><Para>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -