当前位置: 首页 > news >正文

通义千问对postgresql wire协议的连接和执行SQL过程的解释

USER

请说明postgresql wire协议的连接和执行SQL过程

ASSISTANT

PostgreSQL Wire Protocol(也称“前端-后端协议”或“FE/BE协议”)是客户端与PostgreSQL服务器通信的标准二进制协议。它定义了客户端如何连接、认证、发送查询、接收结果等全过程。协议支持两种模式:简单查询协议(Simple Query Protocol)扩展查询协议(Extended Query Protocol)。下面我们将详细说明连接建立和SQL执行的全过程。


一、连接建立过程

1. TCP连接建立

客户端首先通过TCP连接到PostgreSQL服务器的监听端口(默认5432)。

2. 启动消息(StartupMessage)

客户端发送一个 StartupMessage(消息类型无类型字节,长度字段后紧跟协议版本和参数键值对),包含:

  • 协议版本号(如 3.0 → 0x00030000)
  • 连接参数:如 user, database, application_name, client_encoding

示例:

| 长度(4B) | 协议版本(4B) | "user\0postgres\0database\0mydb\0\0" |

注意:StartupMessage 是唯一没有消息类型字节的消息。

3. 服务端响应

服务器根据配置和StartupMessage内容,可能返回以下消息:

  • AuthenticationXXX(如 AuthenticationMD5Password, AuthenticationSASL 等)
  • ErrorResponse(连接失败)
  • BackendKeyData(会话密钥,用于取消查询)
  • ParameterStatus(服务器参数,如 client_encoding, DateStyle 等)
  • ReadyForQuery(表示可以接收查询了,状态字符:I-空闲,T-事务中,E-错误)
认证过程(以MD5为例):
  1. 服务端发送 AuthenticationMD5Password + 4字节盐值。
  2. 客户端计算:MD5(MD5(password + username) + salt),发送 PasswordMessage
  3. 服务端验证,成功则发 AuthenticationOk

4. 连接建立完成

当客户端收到 ReadyForQuery 消息后,连接正式建立,可以开始发送SQL命令。


二、SQL执行过程

PostgreSQL支持两种协议模式执行SQL:


A. 简单查询协议(Simple Query Protocol)

适用于一次性、无参数、不复用的SQL语句。

流程:
  1. 客户端 → 服务端: 发送 Query 消息
    格式:'Q' + 长度 + SQL字符串 + '\0'

    示例:

    Q | len=19 | "SELECT 1 + 1;\0"
    
  2. 服务端响应:

    • RowDescription:描述结果集列(列名、类型OID、格式等)
    • DataRow:每一行数据(二进制或文本格式)
    • CommandComplete:查询完成,包含命令标签(如 “SELECT 1”)
    • ReadyForQuery:准备接收下一条命令

    如果有错误,服务端发送 ErrorResponse,然后仍会发送 ReadyForQuery

特点:
  • 简单直接,适合交互式工具(如 psql)
  • 不支持参数化查询
  • 每次查询都完整解析、计划、执行
  • 无预备语句支持

B. 扩展查询协议(Extended Query Protocol)

支持参数化查询、预备语句、查询计划复用,适合高性能应用(如 JDBC、Go pgx、Python psycopg2)。

主要消息类型:
消息类型说明
Parse解析SQL,生成预备语句(可命名或匿名)
Bind绑定参数值到预备语句,生成“入口”(Portal)
Describe获取预备语句或入口的元数据(如列信息)
Execute执行入口
Sync同步点,强制服务端返回所有结果直到 ReadyForQuery
Close关闭预备语句或入口
典型流程(带参数查询):
  1. Parse

    'P' + len + stmt_name + query + param_type_count + [param_type_oid...]
    

    → 服务端返回 ParseComplete(或 ErrorResponse

  2. Bind

    'B' + len + portal_name + stmt_name + param_format_codes + [param_values...] + result_format_codes
    

    → 服务端返回 BindComplete

  3. Describe(可选)
    用于获取结果集结构(如列名、类型):

    'D' + len + 'P'(Portal)或'S'(Statement) + name
    

    → 服务端返回 RowDescriptionNoData(如INSERT无结果)

  4. Execute

    'E' + len + portal_name + max_rows(0=无限制)
    

    → 服务端返回:

    • DataRow(0或多个)
    • CommandComplete
    • (如有错误 → ErrorResponse
  5. Sync

    'S' + len=4
    

    → 服务端必须返回 ReadyForQuery,保证协议同步

  6. Close(可选)
    清理资源:

    'C' + len + 'S'或'P' + name
    
示例:执行 SELECT * FROM users WHERE id = $1
→ Parse(stmt="", query="SELECT * FROM users WHERE id = $1", types=[int4])
← ParseComplete→ Bind(portal="", stmt="", params=[123])
← BindComplete→ Describe(portal="")
← RowDescription(columns=[...])→ Execute(portal="", max_rows=0)
← DataRow(...)
← CommandComplete("SELECT 1")
← ReadyForQuery('I')

三、事务与错误处理

  • 事务控制:通过SQL语句 BEGIN, COMMIT, ROLLBACK 控制,协议本身无事务消息。
  • 错误处理:任何阶段出错,服务端发送 ErrorResponse,然后必须发送 ReadyForQuery。客户端可继续发送新命令。
  • 取消查询:客户端可通过 CancelRequest 消息(独立TCP连接)中断正在执行的查询。

四、连接关闭

客户端发送 Terminate 消息(‘X’ + 4字节长度),服务端关闭连接。


五、协议版本与兼容性

  • 当前主流版本:v3.0(自 PostgreSQL 7.4 起使用)
  • SSL支持:连接建立后可通过 SSLRequest 升级为加密连接
  • GSSPI/SASL:现代认证机制也通过协议协商支持

总结对比

特性简单查询协议扩展查询协议
参数化❌ 不支持✅ 支持
性能较低(每次解析)较高(可复用执行计划)
使用场景psql、简单脚本应用程序、驱动、ORM
消息复杂度简单复杂(多阶段)
结果集预知执行后才知道可提前Describe获取结构

参考资料

  • PostgreSQL官方文档:Frontend/Backend Protocol
  • Wire协议消息格式详解:Message Flow

通过理解Wire协议,开发者可以更好地调试数据库交互、编写高性能驱动、或实现自定义客户端。主流语言驱动(如 libpq、pgx、psycopg2)均基于此协议实现。

http://www.dtcms.com/a/393070.html

相关文章:

  • 钣金折弯机被远程锁机了怎么办
  • 基于陌讯AIGC检测算法的高性能部署实践:FastAPI与多进程并发设计详解
  • 群晖 NAS 远程访问痛点解决:神卓 N600 公网 IP 盒实战体验
  • JavaWeb之HttpServletRequest与HttpServletResponse详解及快递管理系统实践
  • Git详细介绍
  • 大话计算机网络(上)
  • JVM方法调用机制深度解析:从aload_1到invokevirtual的完整旅程
  • STM32CubeIDE学习——安装
  • 追觅宣布进军手机市场,已经白热化的手机赛道追觅优势何在?
  • AI智能体开发工作流的成功案例分享及思路
  • 【算法基础】String、Hash 与 Stack
  • 使用springboot开发一个宿舍管理系统练习项目
  • 像素版推箱子游戏
  • 2025年CSP-J认证 普及组初赛真题解析 CCF信息学奥赛C++ 中小学初级组 第一轮真题-选择题解析
  • 【精品资料鉴赏】121页可编辑PPT详解医药集团合规管控规划方案
  • Linux用户权限与进程管理深度解析
  • [数据结构] 反射,枚举与lambda表达式
  • 奇异值:数据科学的数学基石与应用核心
  • Python 2025:安全编程与漏洞防范实战指南
  • ​​[硬件电路-286]:高速轨到轨比较器TLV3603DCKR 功能概述与管脚定义
  • CAR 细胞疗法:破解自身免疫性疾病的 “免疫纠错” 新路径
  • FreeRTOS实战指南 — 5 多任务系统实现流程
  • `css`使单词保持连贯的两种方法
  • 【Vue3 ✨】Vue3 入门之旅 · 第三篇:模板语法与数据绑定
  • 分类预测 | Matlab实现PCA-BP主成分分析结合BP神经网络多特征分类预测
  • 【Linux】进程优先级切换调度
  • Ubuntu24上安装Scrapy框架实战
  • 正向shell,反弹shell学习
  • 一维数组原地更新——力扣119.杨辉三角形II
  • Python语法学习-1