Postgres 驱动
这一部分是 sqlx-postgres crate:核心抽象里那些 trait 的 Postgres 实现,以及它和服务端之间的线协议。整个 crate 约 2 万行,types/ 占了 8.8k(每种 Rust 类型的编解码,只挑几个讲),connection/ 2.5k、message/ 2.3k、options/ 1.5k、type_info.rs 1.4k,再加上 listener.rs、copy.rs 等。
前三章是一条连接的生命周期,从下往上:连接怎么建起来,消息怎么收发,一次查询怎么用这些消息拼出来。后三章是建立在它们之上的专题。
- 连接选项与建立连接:
PgConnectOptions依次取环境变量、URL、passfile;establish发SSLRequest(看sslmode)和StartupMessage,走两个 SCRAM-SHA-256 来回,收到ReadyForQuery才交出连接;prefer和require都不校验证书。 - 消息与读写缓冲:一条消息是类型字节加长度;
write_msg只写缓冲,flush才发;recv_unchecked靠try_read做到取消安全;recv截走NoticeResponse和ParameterStatus,把ErrorResponse变成Error::Database,出错之后连接照常可用。 - 扩展查询协议与语句缓存:
pending_ready_for_query_count记着欠服务端几个ReadyForQuery,没读完的结果由下一次查询读掉;StatementCache是按 SQL 原文的 LRU,挤掉一条就发Close;persistent(false)用未命名语句,容量 0 在 0.9.0 里会泄漏。 - Postgres 类型:
PgTypeInfo和 OID;内建类型直接认 OID,自定义类型按名字解析,编码时先留「洞」、拿到 OID 再补;几个代表类型的二进制编码。 - describe 与可空性推断:编译期宏怎么拿到参数和列的类型,以及每一列可不可能是 NULL。
- LISTEN/NOTIFY 与 COPY:
PgListener怎么在一条连接上收通知,COPY的进出两个方向。
flowchart TB opts[PgConnectOptions] --> est["establish 握手"] est --> stream["PgStream 收发消息"] stream --> run["run 扩展查询"] run --> cache[StatementCache] run --> types["PgTypeInfo 与 OID"] run --> desc["describe 给宏用"] stream --> listen["PgListener 与 COPY"]
💬 关联讨论
发起讨论加载中...