支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2

53.1. 概述 #

该协议在启动和正常操作阶段有不同的阶段。在启动阶段,前端打开到服务器的连接,并使服务器满意地进行身份验证。(这可能涉及单个消息,或取决于使用的身份验证方法的多个消息。)如果一切顺利,服务器随后将状态信息发送到前端,最后进入正常操作。除了初始启动请求消息外,协议的这一部分由服务器驱动。

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

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

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

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

53.1.1. 消息传递概述 #

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

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

相反,服务器和客户端都必须注意永远不要发送不完整的消息。通常的做法是在开始发送之前将整个消息编组到缓冲区中。如果发送或接收消息的过程中发生通信故障,唯一合理的响应是放弃连接,因为几乎没有希望恢复消息边界的同步。

53.1.2. 扩展查询概述 #

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

整个执行周期包括解析步骤,该步骤从文本查询字符串创建预备语句;绑定步骤,该步骤在给定预备语句和任何所需参数的值的情况下创建门户;以及执行步骤,该步骤运行门户的查询。对于返回行的查询(SELECTSHOW 等),可以告知执行步骤仅获取有限数量的行,因此可能需要多个执行步骤才能完成操作。

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

53.1.3. 格式和格式代码 #

特定数据类型的数据可能以几种不同的格式传输。自 PostgreSQL 7.4 起,唯一支持的格式是文本二进制,但该协议为未来的扩展提供了规定。任何值的所需格式都由格式代码指定。客户端可以为每个传输的参数值和查询结果的每一列指定格式代码。文本的格式代码为零,二进制的格式代码为一,所有其他格式代码都保留供将来定义。

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

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

提交更正

如果您在文档中看到任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。