2024年9月26日:PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 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 字符串处理,则必须添加一个。(顺便说一句,文本格式不允许嵌入空字符。)

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

提交更正

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