52.1. Overview

该协议具有启动和正常运行的单独阶段。在启动阶段,前端将打开与服务器的连接,并对自身进行身份验证,以使服务器满意。 (根据所使用的身份验证方法,这可能涉及一条消息,也可能涉及多条消息.)如果一切顺利,则服务器会将状态信息发送到前端,最后进入正常操作。除初始启动请求消息外,协议的这一部分由服务器驱动。

在正常操作期间,前端将查询和其他命令发送到后端,后端将向后发送查询结果和其他响应。在少数情况下(例如NOTIFY),后端将发送未经请求的消息,但是在大多数情况下,会话的这一部分是由前端请求驱动的。

通常由前端选择终止会话,但是在某些情况下可以由后端强制终止。无论如何,当后端关闭连接时,它将在退出之前回滚所有打开的(未完成的)事务。

在正常操作中,SQL 命令可以通过两个子协议之一执行。在“简单查询”协议中,前端仅发送文本查询字符串,该字符串将由后端解析并立即执行。在“扩展查询”协议中,查询处理分为多个步骤:解析,参数值绑定和执行。这提供了灵 Active 和性能优势,但付出了额外的复杂性。

正常操作具有用于特殊操作(例如COPY)的附加子协议。

52 .1.1. 讯息概述

所有通信都是通过消息流进行的。消息的第一个字节标识消息的类型,接下来的四个字节指定消息其余部分的长度(此长度计数包括其自身,但不包括消息类型的字节)。消息的其余内容由消息类型确定。由于历史原因,Client 端发送的第一条消息(启动消息)没有初始消息类型字节。

为了避免失去与消息流的同步,服务器和 Client 端通常都会在尝试处理其内容之前,将整个消息读入缓冲区(使用字节数)。如果在处理内容时发现错误,则可以轻松恢复。在极端情况下(例如没有足够的内存来缓冲消息),接收方可以使用字节数来确定在恢复读取消息之前要跳过多少 Importing。

相反,服务器和 Client 端都必须注意不要发送不完整的消息。这通常是通过在开始发送之前在缓冲区中封送整个邮件来完成的。如果在发送或接收消息的途中发生通信故障,则唯一明智的响应是放弃连接,因为恢复消息边界同步的希望很小。

52 .1.2. 扩展查询概述

在扩展查询协议中,SQL 命令的执行分为多个步骤。步骤之间保留的状态由两种类型的对象表示:* prepared statement portals 。一条准备好的语句代表文本查询字符串的解析和语义分析的结果。准备好的语句本身尚不能执行,因为它可能缺少 parameters *的特定值。门户表示已准备好执行或已经部分执行的语句,其中填充了所有缺少的参数值。(对于SELECT语句,门户相当于打开的游标,但是我们选择使用不同的术语,因为游标不会无法处理非SELECT语句.)

整个执行周期包括一个* parse *步骤,该步骤从文本查询字符串创建准备好的语句。 * bind *步骤,该步骤创建一个门户网站,该门户网站给出了准备好的语句和任何所需参数的值;以及执行门户查询的“执行”步骤。对于返回行(SELECTSHOW等)的查询,可以告知执行步骤仅获取有限数量的行,因此可能需要多个执行步骤才能完成操作。

后端可以跟踪多个准备好的语句和门户(但是请注意,这些语句和门户仅存在于一个会话中,并且永远不会在会话之间共享)。现有的准备好的语句和门户网站通过创建时分配的名称进行引用。此外,还存在一个“未命名”的准备好的语句和门户。尽管它们的行为与命名对象基本相同,但是针对仅执行一次查询然后将其丢弃的情况进行了优化,而针对命名对象的操作则针对多次使用进行了优化。

52 .1.3. 格式和格式代码

特定数据类型的数据可能以几种不同的* format 中的任何一种进行传输。从 PostgreSQL 7.4 开始,唯一受支持的格式是“文本”和“二进制”,但是该协议为将来的扩展作了准备。任何值的所需格式都由 format code *指定。Client 端可以为每个传输的参数值和查询结果的每一列指定格式代码。文本的格式代码为零,二进制的格式代码为一,所有其他格式代码均保留以供将来定义。

值的文本表示形式是针对特定数据类型的 Importing/输出转换函数生成并接受的任何字符串。在传输的表示中,没有尾随的空字符。如果前端要将接收的值作为 C 字符串进行处理,则必须将其添加一个。 (顺便说一下,文本格式不允许嵌入空值.)

整数的二进制表示形式使用网络字节 Sequences(最高有效字节在前)。对于其他数据类型,请查阅文档或源代码以了解二进制表示形式。请记住,复杂数据类型的二进制表示形式可能会在服务器版本之间发生变化。文本格式通常是更可移植的选择。