关于 postgresql
根据官方文档生成的 PostgreSQL 参考技能,帮助开发者学习功能与 API、实现数据库方案并调试代码,内容包括 libpq 连接的详细说明。
主要功能
- 01PostgreSQL 功能与 API 指南
- 02实现与调试参考
- 03连接字符串文档
- 04libpq 阻塞与非阻塞连接
适用场景
- 01学习 PostgreSQL 功能
- 02实现数据库连接
- 03调试 libpq 连接代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ 2025emma/ vibe-coding-cn --skill postgresql安装后在 Claude Code 中输入/postgresql确认已加载。
附带文件references/getting_started.mdreferences/index.md
详细介绍
Postgresql 技能
根据官方文档生成的 postgresql 开发全面指南。
何时使用此技能
在以下情况下应触发此技能:
- 使用 postgresql
- 询问 postgresql 功能或 API
- 实现 postgresql 解决方案
- 调试 postgresql 代码
- 学习 postgresql 最佳实践
快速参考
常见模式
模式 1: 32.1. 数据库连接控制函数 # 32.1.1. 连接字符串 32.1.2. 参数关键字
以下函数用于连接到 PostgreSQL 后端服务。应用程序可以同时打开多个后端连接。(其中一个原因是访问多个数据库。)每个连接都由一个 PGconn 对象表示,该对象通过函数 PQconnectdb、PQconnectdbParams 或 PQsetdbLogin 获取。请注意,除非内存不足以分配 PGconn 对象,否则这些函数总会返回非空对象指针。通过连接对象发送查询之前,应调用 PQstatus 函数检查返回值,确认连接成功。
警告
如果不受信任的用户可以访问尚未采用安全模式使用模式的数据库,请在每个会话开始时从 search_path 中移除可公开写入的模式。可以将参数关键字选项设置为 -csearch_path=。或者,连接后执行 PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)")。此注意事项并非 libpq 特有;它适用于所有可执行任意 SQL 命令的接口。
警告
在 Unix 上,使用已打开的 libpq 连接对进程进行分叉,可能导致不可预测的结果,因为父进程和子进程共享相同的套接字和操作系统资源。因此,不建议这样使用,不过子进程执行 exec 以加载新可执行文件是安全的。
PQconnectdbParams #
创建与数据库服务的新连接。
PGconn *PQconnectdbParams(const char * const *keywords, const char * const *values, int expand_dbname);
此函数使用从两个以 NULL 结尾的数组中获取的参数打开新的数据库连接。第一个数组 keywords 是字符串数组,其中每个字符串都是一个关键字。第二个数组 values 提供每个关键字对应的值。与下文的 PQsetdbLogin 不同,参数集可以扩展,而无需更改函数签名,因此新应用程序编程时优先使用此函数(或其非阻塞对应函数 PQconnectStartParams 和 PQconnectPoll)。当前可识别的参数关键字列于第 32.1.2 节。
传入的数组可以为空,以使用所有默认参数;也可以包含一个或多个参数设置。两个数组的长度必须相同。处理会在 keywords 数组中第一个 NULL 项处停止。此外,如果与非 NULL keywords 项关联的 values 项为 NULL 或空字符串,则会忽略该项并继续处理数组中的下一对项。
当 expand_dbname 非零时,会检查第一个 dbname 关键字对应的值,看它是否为连接字符串。如果是,则会将其“展开”为从字符串中提取的各个连接参数。如果该值包含等号(=)或以 URI 方案标识符开头,则会将其视为连接字符串,而非仅仅是数据库名称。(有关连接字符串格式的更多详情,请参见第 32.1.1 节。)只有 dbname 的首次出现会以这种方式处理;后续的任何 dbname 参数都将作为普通数据库名称处理。
通常,参数数组从头到尾依次处理。如果某个关键字重复出现,则使用最后一个非 NULL、非空的值。尤其是当连接字符串中的关键字与 keywords 数组中的关键字冲突时,也适用此规则。因此,程序员可以决定数组项是覆盖还是被连接字符串中的值覆盖。出现在已展开 dbname 项之前的数组项可能被连接字符串中的字段覆盖;而这些字段又会被 dbname 之后的数组项覆盖(同样,只有这些项提供了非空值时才会覆盖)。
处理完所有数组项和任何已展开的连接字符串后,剩余未设置的连接参数将填入默认值。如果未设置参数对应的环境变量(见第 32.15 节)已设置,则使用其值;否则使用该参数的内置默认值。
PQconnectdb #
创建与数据库服务的新连接。
PGconn *PQconnectdb(const char *conninfo);
此函数使用从字符串 conninfo 中获取的参数打开新的数据库连接。传入的字符串可以为空,以使用所有默认参数;也可以包含一个或多个以空格分隔的参数设置,或者包含一个 URI。详情请参见第 32.1.1 节。
PQsetdbLogin #
创建与数据库服务的新连接。
PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd);
这是 PQconnectdb 的前身,参数集固定。它的功能相同,但缺失的参数始终使用默认值。对于要使用默认值的固定参数,可将其写为 NULL 或空字符串。
如果 dbName 包含 = 符号,或带有有效的连接 URI 前缀,则会像传给 PQconnectdb 一样,将其视为 conninfo 字符串;之后,其余参数将按照 PQconnectdbParams 中的说明应用。pgtty 已不再使用,传入的任何值都会被忽略。
PQsetdb #
创建与数据库服务的新连接。
PGconn *PQsetdb(char *pghost, char *pgport, char *pgoptions, char *pgtty, char *dbName);
这是一个宏,会在 login 和 pwd 参数处传入空指针来调用 PQsetdbLogin。提供此宏是为了向后兼容非常旧的程序。
PQconnectStartParamsPQconnectStartPQconnectPoll #
以非阻塞方式连接到数据库服务。
PGconn *PQconnectStartParams(const char * const *keywords, const char * const *values, int expand_dbname); PGconn *PQconnectStart(const char *conninfo); PostgresPollingStatusType PQconnectPoll(PGconn *conn);
这三个函数用于打开与数据库服务的连接,过程中不会阻塞应用程序的执行线程等待远程 I/O。这样做的目的是让 I/O 等待可以在应用程序的主循环中进行,而不是在 PQconnectdbParams 或 PQconnectdb 内部进行;因此,应用程序可以并行管理此操作与其他活动。
对于 PQconnectStartParams,数据库连接使用从 keywords 和 values 数组中获取的参数,并由 expand_dbname 控制,如上文 PQconnectdbParams 所述。对于 PQconnectStart,数据库连接使用从字符串 conninfo 中获取的参数,如上文 PQconnectdb 所述。
只要满足以下若干限制,PQconnectStartParams、PQconnectStart 和 PQconnectPoll 都不会阻塞:
- 必须正确使用 hostaddr 参数,以避免发起 DNS 查询。详情请参见第 32.1.2 节中对此参数的说明。
- 如果调用 PQtrace,请确保要写入跟踪信息的流对象不会阻塞。
- 调用 PQconnectPoll 之前,必须确保套接字处于适当状态,如下所述。
要开始非阻塞连接请求,请调用 PQconnectStart 或 PQconnectStartParams。如果结果为 null,说明 libpq 无法分配新的 PGconn 结构。否则会返回有效的 PGconn 指针(但此时它尚不代表与数据库的有效连接)。
接下来调用 PQstatus(conn)。如果结果为 CONNECTION_BAD,说明连接尝试已经失败,通常是因为连接参数无效。如果 PQconnectStart 或 PQconnectStartParams 成功,下一步便是轮询 libpq,使其继续连接流程。使用 PQsocket(conn) 获取数据库连接底层套接字的描述符。(注意:不要假设套接字在多次调用 PQconnectPoll 之间保持不变。)
按以下方式循环:
- 如果 PQconnectPoll(conn) 上次返回 PGRES_POLLING_READING,则等待套接字准备好读取(由 select()、poll() 或类似的系统函数指示)。请注意,如果系统支持 PQsocketPoll,它可以抽象化 select(2) 或 poll(2) 的设置过程,从而减少样板代码。然后再次调用 PQconnectPoll(conn)。
- 相反,如果 PQconnectPoll(conn) 上次返回 PGRES_POLLING_WRITING,则等待套接字准备好写入,然后再次调用 PQconnectPoll(conn)。
- 在第一次迭代中,也就是尚未调用 PQconnectPoll 时,按其上次返回 PGRES_POLLING_WRITING 处理。
继续循环,直到 PQconnectPoll(conn) 返回 PGRES_POLLING_FAILED(表示连接过程失败)或 PGRES_POLLING_OK(表示连接成功)。
在连接过程中的任何时候,都可以调用 PQstatus 检查连接状态。如果此调用返回 CONNECTION_BAD,则连接过程失败;如果返回 CONNECTION_OK,则连接已就绪。这两种状态都可以通过上述 PQconnectPoll 的返回值检测到。在异步连接过程中(且仅在此过程中)还可能出现其他状态。这些状态表示连接过程的当前阶段,例如可用于向用户提供反馈。状态如下:
CONNECTION_STARTED # 正在等待建立连接。 CONNECTION_MADE # 连接正常;等待发送。 CONNECTION_AWAITING_RESPONSE # 正在等待服务响应。 CONNECTION_AUTH_OK # 已收到身份验证结果;等待后端启动完成。 CONNECTION_SSL_STARTUP # 正在协商 SSL 加密。 CONNECTION_GSS_STARTUP # 正在协商 GSS 加密。 CONNECTION_CHECK_WRITABLE # 正在检查连接是否能够处理写事务。 CONNECTION_CHECK_STANDBY # 正在检查连接是否连接到备用模式的服务。 CONNECTION_CONSUME # 正在接收连接上剩余的响应消息。
请注意,尽管这些常量会保留(以保持兼容性),应用程序绝不能依赖它们以特定顺序出现、一定出现,或状态始终是这些已记录的值之一。
应用程序可以按如下方式处理:
switch(PQstatus(conn)) { case CONNECTION_STARTED: feedback = "Connecting..."; break; case CONNECTION_MADE: feedback = "Connected to server..."; break; . . . default: feedback = "Connecting..."; }
使用 PQconnectPoll 时,connect_timeout 连接参数会被忽略;应用程序需要自行判断是否已经经过了过长时间。除此之外,PQconnectStart 后接 PQconnectPoll 循环的效果等同于 PQconnectdb。
请注意,当 PQconnectStart 或 PQconnectStartParams 返回非空指针时,使用完毕后必须调用 PQfinish,以释放该结构及其关联的内存块。即使连接尝试失败或被放弃,也必须执行此操作。
PQsocketPoll #
轮询通过 PQsocket 获取的连接底层套接字描述符。
此函数的主要用途是遍历 PQconnectStartParams 文档中所述的连接流程。
typedef int64_t pg_usec_time_t; int PQsocketPoll(int sock, int forRead, int forWrite, pg_usec_time_t end_time);
此函数轮询文件描述符,可选择设置超时。如果 forRead 非零,则套接字准备好读取时函数会终止;如果 forWrite 非零,则套接字准备好写入时函数会终止。超时时间由 end_time 指定,它是自 Unix 纪元以来的微秒数(即 time_t 乘以 1 million)。如果 end_time 为 -1,则超时时间为无限。如果 end_time 为 0(或任何早于当前时间的值),则立即超时(不阻塞)。可以将所需的微秒数加到 PQgetCurrentTimeUSec 的结果上,方便地计算超时值。
请注意,底层系统调用的精度可能低于微秒,因此实际延迟可能并不精确。如果指定条件满足,函数返回大于 0 的值;如果发生超时,则返回 0;如果发生错误,则返回 -1。可以通过检查 errno(3) 的值获取错误。如果 forRead 和 forWrite 都为零,函数会立即返回超时指示。
PQsocketPoll 根据平台使用 poll(2) 或 select(2) 实现。详情请参见 poll(2) 中的 POLLIN 和 POLLOUT,或 select(2) 中的 readfds 和 writefds。
PQconndefaults #
返回默认连接选项。
PQconninfoOption *PQconndefaults(void);
typedef struct { char keyword; / 选项的关键字 */ char envvar; / 回退环境变量名称 */ char compiled; / 编译时的回退默认值 */ char val; / 选项的当前值,或 NULL */ char label; / 连接对话框中字段的标签 / char dispchar; / 指示在连接对话框中如何显示此字段。取值如下: "" 原样显示输入的值 "" 密码字段——隐藏值 "D" 调试选项——默认不显示 / int dispsize; / 对话框中字段的字符宽度 */ } PQconninfoOption;
返回一个连接选项数组。可以用它确定所有可能的 PQconnectdb 选项及其当前默认值。返回值指向一个 PQconninfoOption 结构数组,该数组以 keyword 指针为 null 的项结尾。如果无法分配内存,则返回 null 指针。
请注意,当前默认值(val 字段)取决于环境变量和其他上下文。缺失或无效的服务文件会被静默忽略。调用方必须将连接选项数据视为只读。处理完选项数组后,将其传给 PQconninfoFree 以释放。如果未这样做,每次调用 PQconndefaults 都会泄漏少量内存。
PQconninfo #
返回活动连接所使用的连接选项。
PQconninfoOption *PQconninfo(PGconn *conn);
返回一个连接选项数组。可以用它确定所有可能的 PQconnectdb 选项,以及用于连接到服务的值。返回值指向一个 PQconninfoOption 结构数组,该数组以 keyword 指针为 null 的项结尾。上文关于 PQconndefaults 的所有说明同样适用于 PQconninfo 的结果。
PQconninfoParse #
返回从给定连接字符串解析出的连接选项。
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
解析连接字符串并将得到的选项作为数组返回;如果连接字符串有问题,则返回 NULL。可以使用此函数提取给定连接字符串中的 PQconnectdb 选项。返回值指向一个 PQconninfoOption 结构数组,该数组以 keyword 指针为 null 的项结尾。所有合法选项都会出现在结果数组中,但连接字符串中未出现的选项,其 PQconninfoOption 的 val 会设为 NULL;不会插入默认值。
如果 errmsg 非 NULL,则成功时会将 *errmsg 设为 NULL,否则会将其设为解释问题的 malloc'd 错误字符串。(也可能出现 *errmsg 为 NULL 且函数返回 NULL 的情况;这表示内存不足。)
处理完选项数组后,将其传给 PQconninfoFree 以释放。如果未这样做,每次调用 PQconninfoParse 都会泄漏一些内存。相反,如果发生错误且 errmsg 非 NULL,请务必使用 PQfreemem 释放错误字符串。
PQfinish #
关闭与服务的连接,并释放 PGconn 对象使用的内存。
void PQfinish(PGconn *conn);
请注意,即使连接服务的尝试失败(由 PQstatus 指示),应用程序也应调用 PQfinish,以释放 PGconn 对象使用的内存。调用 PQfinish 后,不得再次使用 PGconn 指针。
PQreset #
重置与服务的通信通道。
void PQreset(PGconn *conn);
此函数会关闭与服务的连接,并尝试使用之前的所有相同参数建立新连接。如果正常工作的连接丢失,此函数可用于错误恢复。
PQresetStartPQresetPoll #
以非阻塞方式重置与服务的通信通道。
int PQresetStart(PGconn *conn); PostgresPollingStatusType PQresetPoll(PGconn *conn);
这些函数会关闭与服务的连接,并尝试使用之前的所有相同参数建立新连接。如果正常工作的连接丢失,这些函数可用于错误恢复。与上文的 PQreset 不同,它们以非阻塞方式运行。这些函数与 PQconnectStartParams、PQconnectStart 和 PQconnectPoll 有相同的限制。
要启动连接重置,请调用 PQresetStart。如果返回 0,则重置失败。如果返回 1,则使用 PQresetPoll 轮询重置,方式与使用 PQconnectPoll 创建连接完全相同。
PQpingParams #
PQpingParams 报告服务的状态。它接受的连接参数与上文所述的 PQconnectdbParams 完全相同。获取服务状态不需要提供正确的用户名、密码或数据库名称;不过,如果提供了错误的值,服务会记录一次失败的连接尝试。
PGPing PQpingParams(const char * const *keywords, const char * const *values, int expand_dbname);
函数返回以下值之一:
PQPING_OK # 服务正在运行,似乎可以接受连接。 PQPING_REJECT # 服务正在运行,但处于不允许连接的状态(启动、关闭或崩溃恢复)。 PQPING_NO_RESPONSE # 无法联系服务。这可能表示服务未运行、给定的连接参数有误(例如端口号错误),或存在网络连接问题(例如防火墙阻止了连接请求)。 PQPING_NO_ATTEMPT # 未尝试联系服务,因为提供的参数明显有误,或客户端存在问题(例如内存不足)。
PQping #
PQping 报告服务的状态。它接受的连接参数与上文所述的 PQconnectdb 完全相同。获取服务状态不需要提供正确的用户名、密码或数据库名称;不过,如果提供了错误的值,服务会记录一次失败的连接尝试。
PGPing PQping(const char *conninfo);
返回值与 PQpingParams 相同。
PQsetSSLKeyPassHook_OpenSSL #
PQsetSSLKeyPassHook_OpenSSL 允许应用程序覆盖 libpq 使用 sslpassword 或交互式提示处理加密客户端证书密钥文件的默认方式。
void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);
应用程序传入一个指向回调函数的指针,其签名如下:
int callback_fn(char *buf, int size, PGconn *conn);
之后,libpq 会调用此函数,而不是默认的 PQdefaultSSLKeyPassHook_OpenSSL 处理函数。回调应确定密钥的密码,并将其复制到大小为 size 的结果缓冲区 buf 中。buf 中的字符串必须以 null 结尾。回调必须返回 buf 中所存密码的长度,不包括 null 终止符。如果失败,回调应将 buf[0] 设为 '\0' 并返回 0。示例请参见 libpq 源代码中的 PQdefaultSSLKeyPassHook_OpenSSL。
如果用户指定了显式的密钥位置,调用回调时该路径会位于 conn->sslkey 中。如果使用默认密钥路径,此值将为空。对于作为引擎标识符的密钥,由引擎实现决定是否使用 OpenSSL 密码回调,或定义自己的处理方式。
应用程序回调可以选择将未处理的情况委托给 PQdefaultSSLKeyPassHook_OpenSSL,也可以先调用它,并在其返回 0 时尝试其他处理方式,或者完全覆盖它。回调不得使用异常、longjmp(...) 等方式跳出正常控制流,必须正常返回。
PQgetSSLKeyPassHook_OpenSSL #
PQgetSSLKeyPassHook_OpenSSL 返回当前客户端证书密钥密码钩子;如果未设置,则返回 NULL。
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void);
32.1.1. 连接字符串 #
多个 libpq 函数会解析用户指定的字符串以获取连接参数。这些字符串接受两种格式:普通关键字/值字符串和 URI。URI 通常遵循 RFC 3986,但允许多主机连接字符串,详情见下文。
32.1.1.1. 关键字/值连接字符串 #
在关键字/值格式中,每个参数设置的形式为 keyword = value,各设置之间以空格分隔。设置等号两侧的空格可有可无。要指定空值或包含空格的值,请用单引号括起来,例如 keyword = 'a value'。值中的单引号和反斜杠必须用反斜杠转义,即 ' 和 \。
示例:
host=localhost port=5432 dbname=mydb connect_timeout=10
可识别的参数关键字列于第 32.1.2 节。
32.1.1.2. 连接 URI #
连接 URI 的一般形式为:
postgresql://[userspec@][hostspec][/dbname][?paramspec]
其中 userspec 为:
user[:password]
hostspec 为:
[host][:port][,...]
paramspec 为:
name=value[&...]
URI 方案标识符可以是 postgresql:// 或 postgres://。其余 URI 部分均为可选。以下示例展示了有效的 URI 语法:
postgresql:// postgresql://localhost postgresql://localhost:5433 postgresql://localhost/mydb postgresql://user@localhost postgresql://user:secret@localhost postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp
通常出现在 URI 层次部分的值,也可以作为命名参数提供。例如:
postgresql:///mydb?host=localhost&port=5433
除为兼容 JDBC 连接 URI 而将 ssl=true 转换为 sslmode=require 的情况外,所有命名参数都必须匹配第 32.1.2 节中列出的关键字。
如果连接 URI 的任何部分包含具有特殊含义的符号,则必须使用百分号编码。例如,下面的示例中,等号(=)替换为 %3D,空格替换为 %20:
postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff
host 部分可以是主机名或 IP 地址。要指定 IPv6 地址,请用方括号括起来:
postgresql://[2001:db8::1234]/database
host 部分的解释方式与 host 参数相同。特别是,如果 host 部分为空或看起来像绝对路径名,则会选择 Unix 域套接字连接;否则会发起 TCP/IP 连接。但请注意,斜杠是 URI 层次部分中的保留字符。因此,要指定非标准 Unix 域套接字目录,可以省略 URI 的 host 部分,并将 host 指定为命名参数;也可以对 URI 的 host 部分中的路径进行百分号编码:
postgresql:///dbname?host=/var/lib/postgresql postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
可以在单个 URI 中指定多个 host 部分,每个部分都可以包含可选的 port 部分。形式为 postgresql://host1:port1,host2:port2,host3:port3/ 的 URI 等同于形式为 host=host1,host2,host3 port=port1,port2,port3 的连接字符串。如下文所述,会依次尝试每个主机,直到成功建立连接。
32.1.1.3. 指定多个主机 #
可以指定多个待连接的主机,连接时会按给定顺序依次尝试。在关键字/值格式中,host、hostaddr 和 port 选项都接受以逗号分隔的值列表。指定的每个选项中的元素数量必须相同,以确保第一个 hostaddr 对应第一个主机名、第二个 hostaddr 对应第二个主机名,依此类推。例外情况是,如果只指定一个 port,它会应用于所有主机。
在连接 URI 格式中,可以在 URI 的 host 部分中列出多个 host:port 对,并用逗号分隔。
无论使用哪种格式,单个主机名都可能对应多个网络地址。常见示例是同时具有 IPv4 和 IPv6 地址的主机。指定多个主机,或单个主机名对应多个地址时,会按顺序尝试所有主机和地址,直到成功为止。如果所有主机都无法访问,连接就会失败。如果成功建立连接,但身份验证失败,则不会尝试列表中的其余主机。
如果使用密码文件,可以为不同主机设置不同密码。列表中所有主机的其他连接选项都相同;例如,无法为不同主机指定不同用户名。
32.1.2. 参数关键字 #
当前可识别的参数关键字如下:
host #
要连接的主机名称。如果主机名看起来像绝对路径名,则表示使用 Unix 域通信而非 TCP/IP 通信;其值为存放套接字文件的目录名称。(在 Unix 上,绝对路径名以斜杠开头。在 Windows 上,也能识别以驱动器号开头的路径。)
如果主机名以 @ 开头,则会将其视为抽象命名空间中的 Unix 域套接字(目前 Linux 和 Windows 支持此功能)。
未指定 host 或其值为空时,默认连接到 /tmp 中的 Unix 域套接字(或 PostgreSQL 构建时指定的套接字目录)。在 Windows 上,默认连接到 localhost。
也接受以逗号分隔的主机名列表,此时会按顺序尝试列表中的每个主机名;列表中的空项会选择上述默认行为。详情请参见第 32.1.1.3 节。
hostaddr #
要连接的主机的数字 IP 地址。格式应为标准 IPv4 地址,例如 172.28.40.9。如果计算机支持 IPv6,也可以使用 IPv6 地址。只要此参数指定了非空字符串,就始终使用 TCP/IP 通信。
如果未指定此参数,则会查找 host 的值以确定对应的 IP 地址;如果 host 指定的是 IP 地址,则直接使用该值。
使用 hostaddr 可以让应用程序避免主机名查找,这对于受时间限制的应用程序可能很重要。不过,GSSAPI 或 SSPI 身份验证方法以及 verify-full SSL 证书验证都需要主机名。具体规则如下:
- 如果指定了 host 而未指定 hostaddr,则会执行主机名查找。(使用 PQconnectPoll 时,在 PQconnectPoll 首次处理此主机名时执行查找,且可能导致 PQconnectPoll 长时间阻塞。)
- 如果指定了 hostaddr 而未指定 host,则 hostaddr 的值提供服务的网络地址。如果身份验证方法需要主机名,连接尝试将失败。
- 如果同时指定了 host 和 hostaddr,则 hostaddr 的值提供服务的网络地址。除非身份验证方法需要主机名,否则会忽略 host;如果需要,则将其用作主机名。请注意,如果 host 不是网络地址 hostaddr 对应的服务名称,身份验证可能会失败。此外,同时指定 host 和 hostaddr 时,host 会用于在密码文件中识别连接(见第 32.16 节)。
也接受以逗号分隔的 hostaddr 值列表,此时会按顺序尝试列表中的每个主机。如果列表中有空项,则会使用对应的主机名;如果该主机名也为空,则使用默认主机名。详情请参见第 32.1.1.3 节。
如果既未指定主机名也未指定主机地址,libpq 将通过本地 Unix 域套接字连接;在 Windows 上,则会尝试连接到 localhost。
port #
要连接的服务主机端口号;对于 Unix 域连接,则为套接字文件扩展名。
如果在 host 或 hostaddr 参数中指定了多个主机,此参数可以指定以逗号分隔、元素数量与主机列表相同的端口列表,也可以指定一个供所有主机使用的端口号。空字符串,或逗号分隔列表中的空项,表示使用 PostgreSQL 构建时确定的默认端口号。
dbname #
数据库名称。默认与用户名相同。在某些上下文中,会检查该值是否属于扩展格式;详情请参见第 32.1.1 节。
user #
要使用的 PostgreSQL 用户名。默认与运行应用程序的操作系统用户名称相同。
password #
如果服务要求密码身份验证,则使用此密码。
passfile #
指定用于存储密码的文件名称(见第 32.16 节)。默认值为 ~/.pgpass;在 Microsoft Windows 上为 %APPDATA%\postgresql\pgpass.conf。(如果此文件不存在,不会报告错误。)
require_auth #
指定客户端要求服务使用的身份验证方法。如果服务未使用所要求的方法对客户端进行身份验证,或者服务未完整完成身份验证握手,则连接将失败。也可以提供以逗号分隔的方法列表,服务必须恰好使用其中一种方法才能建立连接。默认情况下,接受任何身份验证方法,服务也可以完全跳过身份验证。
可以在方法前加上 ! 前缀来否定该方法;此时服务不得尝试列出的方法,但可以使用其他任何方法,也可以完全不对客户端进行身份验证。如果提供了以逗号分隔的列表,服务不得尝试其中任何被否定的方法。否定和非否定形式不能在同一设置中混用。
最后一种特殊情况是,none 方法要求服务不得使用身份验证质询。(也可以对其取反,以要求使用某种形式的身份验证。)
可指定以下方法:
password
服务必须请求明文密码身份验证。
md5
服务必须请求 MD5 哈希密码身份验证。
警告
对 MD5 加密密码的支持已弃用,并将在 PostgreSQL 的未来版本中移除。有关迁移到其他密码类型的详情,请参见第 20.5 节。
gss
服务必须通过 GSSAPI 请求 Kerberos 握手,或建立 GSS 加密通道(另见 gssencmode)。
sspi
服务必须请求 Windows SSPI 身份验证。
scram-sha-256
服务必须成功与客户端完成 SCRAM-SHA-256 身份验证交换。
oauth
服务必须向客户端请求 OAuth 持有者令牌。
none
服务不得提示客户端进行身份验证交换。(这不禁止通过 TLS 进行客户端证书身份验证,也不禁止通过其加密传输进行 GSS 身份验证。)
channel_binding #
此选项控制客户端是否使用通道绑定。设为 require 表示连接必须使用通道绑定;设为 prefer 表示如果通道绑定可用,客户端就会选择使用;设为 disable 则禁止使用通道绑定。如果 PostgreSQL 在编译时启用了 SSL 支持,默认值为 prefer;否则默认值为 disable。
通道绑定是一种让服务向客户端验证自身身份的方法。此功能仅支持与 PostgreSQL 11 或更高版本的服务通过 SSL 连接,并使用 SCRAM 身份验证方法。
connect_timeout #
连接时的最大等待时间,单位为秒(写作十进制整数,例如 10)。设为零、负数或不指定,均表示无限期等待。此超时分别应用于每个主机名或 IP 地址。例如,如果指定了两个主机且 connect_timeout 为 5,那么如果 5 秒内未建立连接,每个主机都会超时,因此连接等待的总时间最多可能达到 10 秒。
client_encoding #
为此连接设置 client_encoding 配置参数。除了可使用对应服务选项接受的值外,还可以使用 auto,根据客户端当前区域设置确定正确的编码(Unix 系统上为 LC_CTYPE 环境变量)。
options #
指定在连接开始时发送给服务的命令行选项。例如,将其设为 -c geqo=off 或 --geqo=off,可将会话的 geqo 参数值设为 off。此字符串中的空格会被视为命令行参数分隔符,除非使用反斜杠(\)转义;写作 \ 表示一个字面反斜杠。有关可用选项的详细说明,请参见第 19 章。
application_name #
为 application_name 配置参数指定一个值。
fallback_application_name #
为 application_name 配置参数指定一个回退值。如果连接参数或 PGAPPNAME 环境变量均未提供 application_name 的值,则会使用此值。在通用实用程序中指定回退名称很有用,这类程序可以设置默认应用程序名称,同时允许用户覆盖它。
keepalives #
控制是否使用客户端 TCP keepalive。默认值为 1,表示启用;如果不需要 keepalive,可以将其设为 0,表示禁用。对于通过 Unix 域套接字建立的连接,此参数会被忽略。
keepalives_idle #
控制 TCP 在多少秒无活动后向服务发送 keepalive 消息。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,或禁用 keepalive 时,此参数会被忽略。此参数仅在支持 TCP_KEEPIDLE 或等效套接字选项的系统以及 Windows 上受支持;在其他系统上不起作用。
keepalives_interval #
控制 TCP keepalive 消息未收到服务确认后,等待多少秒再重新发送。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,或禁用 keepalive 时,此参数会被忽略。此参数仅在支持 TCP_KEEPINTVL 或等效套接字选项的系统以及 Windows 上受支持;在其他系统上不起作用。
keepalives_count #
控制客户端与服务之间的连接在被视为断开之前,可以丢失多少个 TCP keepalive。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,或禁用 keepalive 时,此参数会被忽略。此参数仅在支持 TCP_KEEPCNT 或等效套接字选项的系统上受支持;在其他系统上不起作用。
tcp_user_timeout #
控制已发送数据在连接被强制关闭之前可以保持未确认状态的毫秒数。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,此参数会被忽略。此参数仅在支持 TCP_USER_TIMEOUT 的系统上受支持;在其他系统上不起作用。
replication #
此选项决定连接是否使用复制协议,而非普通协议。PostgreSQL 复制连接以及 pg_basebackup 等工具在内部都会使用此协议,但第三方应用程序也可以使用。有关复制协议的说明,请参见第 54.4 节。
支持以下值,且不区分大小写:
true、on、yes、1
连接进入物理复制模式。
database
连接进入逻辑复制模式,并连接到 dbname 参数指定的数据库。
false、off、no、0
连接为普通连接,这是默认行为。
在物理或逻辑复制模式下,只能使用简单查询协议。
gssencmode #
此选项决定是否与服务协商安全 GSS TCP/IP 连接,以及协商时的优先级。共有三种模式:
disable
仅尝试非 GSSAPI 加密连接。
prefer(默认)
如果存在 GSSAPI 凭据(即凭据缓存中有凭据),则先尝试 GSSAPI 加密连接;如果失败或不存在凭据,则尝试非 GSSAPI 加密连接。这是 PostgreSQL 在编译时启用 GSSAPI 支持时的默认值。
require
仅尝试 GSSAPI 加密连接。
对于 Unix 域套接字通信,gssencmode 会被忽略。
如果 PostgreSQL 在编译时未启用 GSSAPI 支持,使用 require 选项会导致错误;使用 prefer 会被接受,但 libpq 实际上不会尝试 GSSAPI 加密连接。
sslmode #
此选项决定是否与服务协商安全 SSL TCP/IP 连接,以及协商时的优先级。共有六种模式:
disable
仅尝试非 SSL 连接。
allow
先尝试非 SSL 连接;如果失败,再尝试 SSL 连接。
prefer(默认)
先尝试 SSL 连接;如果失败,再尝试非 SSL 连接。
require
仅尝试 SSL 连接。如果存在根 CA 文件,则会像指定 verify-ca 一样验证证书。
verify-ca
仅尝试 SSL 连接,并验证服务证书是否由受信任的证书颁发机构(CA)签发。
verify-full
仅尝试 SSL 连接,验证服务证书是否由受信任的 CA 签发,并验证请求的服务主机名是否与证书中的主机名匹配。
有关这些选项工作方式的详细说明,请参见第 32.19 节。对于 Unix 域套接字通信,sslmode 会被忽略。
如果 PostgreSQL 在编译时未启用 SSL 支持,使用 require、verify-ca 或 verify-full 选项会导致错误;使用 allow 和 prefer 会被接受,但 libpq 实际上不会尝试 SSL 连接。
请注意,如果可以使用 GSSAPI 加密,则无论 sslmode 的值如何,都会优先使用 GSSAPI 加密,而非 SSL 加密。若要在具备可用 GSSAPI 基础设施(例如 Kerberos 服务)的环境中强制使用 SSL 加密,还应将 gssencmode 设为 disable。
requiressl #
此选项已弃用,应使用 sslmode 设置替代。设为 1 时,必须与服务建立 SSL 连接(等同于 sslmode require)。如果服务不接受 SSL 连接,libpq 将拒绝连接。设为 0(默认值)时,libpq 会与服务协商连接类型(等同于 sslmode prefer)。仅当 PostgreSQL 在编译时启用了 SSL 支持时,此选项才可用。
sslnegotiation #
如果使用 SSL,此选项控制如何与服务协商 SSL 加密。在默认的 postgres 模式下,客户端先询问服务是否支持 SSL。在 direct 模式下,客户端建立 TCP/IP 连接后直接开始标准 SSL 握手。传统的 PostgreSQL 协议协商方式与不同的服务配置最为兼容。如果确认服务支持直接 SSL 连接,则后一种方式可少进行一次往返,从而降低连接延迟,并允许使用与协议无关的 SSL 网络工具。直接 SSL 选项在 PostgreSQL 17 版本中引入。
postgres
执行 PostgreSQL 协议协商。如果未提供此选项,这是默认值。
direct
建立 TCP/IP 连接后直接开始 SSL 握手。此模式仅允许与 sslmode=require 或更高要求的设置搭配使用,因为较弱的设置可能在服务不支持直接 SSL 握手时,导致意外回退到明文身份验证。
sslcompression #
设为 1 时,通过 SSL 连接发送的数据会被压缩。设为 0 时会禁用压缩。默认值为 0。建立不使用 SSL 的连接时,此参数会被忽略。
如今,SSL 压缩被认为不安全,因此不再建议使用。OpenSSL 1.1.0 默认禁用了压缩,许多操作系统发行版也在更早版本中禁用了压缩,因此如果服务不接受压缩,将此参数设为 on 不会产生任何效果。PostgreSQL 14 在后端中完全禁用了压缩。
如果安全性并非首要考虑因素,且网络是瓶颈,压缩可以提高吞吐量。如果 CPU 性能是限制因素,禁用压缩可以改善响应时间和吞吐量。
sslcert #
此参数指定客户端 SSL 证书的文件名,替代默认文件 ~/.postgresql/postgresql.crt。未建立 SSL 连接时,此参数会被忽略。
sslkey #
此参数指定客户端证书所用私钥的位置。它可以指定一个文件名,以替代默认文件 ~/.postgresql/postgresql.key;也可以指定从外部“引擎”(引擎是可加载的 OpenSSL 模块)获取的密钥。外部引擎的指定格式应由引擎名称和特定于引擎的密钥标识符组成,两者以冒号分隔。未建立 SSL 连接时,此参数会被忽略。
sslkeylogfile #
此参数指定 libpq 记录此 SSL 上下文中所用密钥的位置。这对于使用 Wireshark 等网络检查工具调试 PostgreSQL 协议交互或客户端连接很有用。未建立 SSL 连接或使用 LibreSSL 时,此参数会被忽略(LibreSSL 不支持密钥记录)。密钥会以 NSS 格式记录。
警告
记录密钥会在密钥日志文件中暴露可能敏感的信息。密钥日志文件应与 sslkey 文件同等谨慎处理。
sslpassword #
此参数指定 sslkey 中所指定私钥的密码,即使不方便交互式输入密码短语,也可以将客户端证书私钥以加密形式存储在磁盘上。将此参数设为任何非空值,都会抑制 OpenSSL 在 libpq 收到加密客户端证书密钥时默认发出的 Enter PEM pass phrase: 提示。如果密钥未加密,则会忽略此参数。
除非 OpenSSL 引擎使用 OpenSSL 密码回调机制处理提示,否则此参数不会影响由 OpenSSL 引擎指定的密钥。此选项没有对应的环境变量,也无法从 .pgpass 中查找密码。可以在服务文件的连接定义中使用此选项。用法更复杂的用户可考虑使用 OpenSSL 引擎以及 PKCS#11 或 USB 加密卸载设备等工具。
sslcertmode #
此选项决定是否可以向服务发送客户端证书,以及是否要求服务请求证书。共有三种模式:
disable
即使有可用证书,也从不发送客户端证书(默认位置中的证书或通过 sslcert 提供的证书均不例外)。
allow(默认)
如果服务请求证书且客户端有可发送的证书,则可以发送。
require
服务必须请求证书。如果客户端未发送证书,但服务仍成功对客户端进行身份验证,则连接将失败。
注意
sslcertmode=require 不会增加任何额外安全性,因为无法保证服务是否正确验证证书;PostgreSQL 服务通常会向客户端请求 TLS 证书,无论是否验证这些证书。此选项可能有助于排查更复杂的 TLS 设置问题。
sslrootcert #
此参数指定一个包含 SSL 证书颁发机构(CA)证书的文件名称。如果文件存在,则会验证服务证书是否由其中某个机构签发。默认值为 ~/.postgresql/root.crt。也可以指定特殊值 system,此时会加载 SSL 实现提供的受信任 CA 根证书。这些根证书的具体位置因 SSL 实现和平台而异。对于 OpenSSL,SSL_CERT_DIR 和 SSL_CERT_FILE 环境变量还可能进一步修改这些位置。
注意
使用 sslrootcert=system 时,默认 sslmode 会变为 verify-full,任何较弱的设置都会导致错误。在大多数情况下,任何人都很容易获得系统信任的、适用于其所控制主机名的证书,这会使 verify-ca 及所有更弱的模式失去作用。特殊值 system 的优先级高于同名的本地证书文件。如果因某些原因遇到这种情况,请改用其他路径,例如 sslrootcert=./system。
sslcrl #
此参数指定 SSL 服务证书吊销列表(CRL)的文件名。如果文件存在,则在尝试验证服务证书时会拒绝其中列出的证书。如果 sslcrl 和 sslcrldir 均未设置,此项将使用 ~/.postgresql/root.crl。
sslcrldir #
此参数指定 SSL 服务证书吊销列表(CRL)的目录名称。如果目录存在,则在尝试验证服务证书时会拒绝其中各文件列出的证书。需要使用 OpenSSL 命令 openssl rehash 或 c_rehash 准备此目录。详情请参见相关文档。sslcrl 和 sslcrldir 可以同时指定。
sslsni #
设为 1(默认值)时,libpq 会在启用 SSL 的连接上设置 TLS 扩展“服务器名称指示”(SNI)。将此参数设为 0 可关闭此功能。SSL 感知型代理可以使用服务器名称指示来路由连接,而无需解密 SSL 数据流。(请注意,除非代理能识别 PostgreSQL 协议握手,否则需要将 sslnegotiation 设为 direct。)不过,SNI 会使目标主机名以明文形式出现在网络流量中,因此在某些情况下可能不合适。
requirepeer #
此参数指定服务的操作系统用户名,例如 requirepeer=postgres。建立 Unix 域套接字连接时,如果设置了此参数,客户端会在连接开始时检查服务进程是否以指定用户名运行;如果不是,则会中止连接并报错。
此参数可用于提供类似 TCP/IP 连接中 SSL 证书所提供的服务身份验证。(请注意,如果 Unix 域套接字位于 /tmp 或其他可公开写入的位置,任何用户都可以在该处启动正在监听的服务。请使用此参数确保连接到由受信任用户运行的服务。)
此选项仅在实现了对端身份验证方法的平台上受支持;请参见第 20.9 节。
ssl_min_protocol_version #
此参数指定连接允许使用的最低 SSL/TLS 协议版本。有效值为 TLSv1、TLSv1.1、TLSv1.2 和 TLSv1.3。支持的协议取决于所用 OpenSSL 的版本,较旧版本不支持最新的协议版本。如果未指定,默认值为 TLSv1.2,符合本文编写时的行业最佳实践。
ssl_max_protocol_version #
此参数指定连接允许使用的最高 SSL/TLS 协议版本。有效值为 TLSv1、TLSv1.1、TLSv1.2 和 TLSv1.3。支持的协议取决于所用 OpenSSL 的版本,较旧版本不支持最新的协议版本。如果未设置此参数,则会忽略它,连接将使用后端定义的最高版本(如果有)。设置最高协议版本主要用于测试,或在某些组件无法正常使用较新协议时使用。
min_protocol_version #
指定连接允许使用的最低协议版本。默认情况下,允许使用 libpq 支持的任何 PostgreSQL 协议版本,目前为 3.0。如果服务不支持至少此版本的协议,连接将关闭。目前支持的值为 3.0、3.2 和 latest。latest 表示所用 libpq 版本支持的最新协议版本,目前为 3.2。
max_protocol_version #
指定向服务请求的协议版本。默认使用 PostgreSQL 协议 3.0 版,除非连接字符串指定了依赖更高协议版本的功能,此时会使用 libpq 支持的最新版本。如果服务不支持客户端请求的协议版本,连接会自动降级到服务支持的较低次版本。连接尝试完成后,可以使用 PQprotocolVersion 查明实际协商的确切协议版本。目前支持的值为 3.0、3.2 和 latest。latest 表示所用 libpq 版本支持的最新协议版本,目前为 3.2。
krbsrvname #
使用 GSSAPI 身份验证时所用的 Kerberos 服务名称。此名称必须与服务配置中指定的名称一致,Kerberos 身份验证才能成功。(另见第 20.6 节。)默认值通常为 postgres,但在构建 PostgreSQL 时,可以通过 configure 的 --with-krb-srvnam 选项修改此值。在大多数环境中,无需更改此参数。某些 Kerberos 实现可能需要不同的服务名称,例如 Microsoft Active Directory 要求服务名称使用大写字母(POSTGRES)。
gsslib #
用于 GSSAPI 身份验证的 GSS 库。目前仅在同时包含 GSSAPI 和 SSPI 支持的 Windows 构建中生效。在此类构建中,将其设为 gssapi 可使 libpq 在身份验证时使用 GSSAPI 库,而非默认的 SSPI。
gssdelegation #
将 GSS 凭据转发(委派)给服务。默认值为 0,表示不会将凭据转发给服务。设为 1 时,会在可能的情况下转发凭据。
scram_client_key #
经过 base64 编码的 SCRAM 客户端密钥。外部数据包装器或类似中间件可以使用此选项启用 SCRAM 透传身份验证。此类实现的一个示例请参见第 F.38.1.10 节。此参数不供用户或客户端应用程序直接指定。
scram_server_key #
经过 base64 编码的 SCRAM 服务端密钥。外部数据包装器或类似中间件可以使用此选项启用 SCRAM 透传身份验证。此类实现的一个示例请参见第 F.38.1.10 节。此参数不供用户或客户端应用程序直接指定。
service #
用于附加参数的服务名称。它指定 pg_service.conf 中包含附加连接参数的服务名称。这样,应用程序只需指定服务名称即可集中维护连接参数。请参见第 32.17 节。
target_session_attrs #
此选项决定会话是否必须具备某些属性才可接受。通常会与多个主机名搭配使用,以从多个主机中选择第一个符合条件的选项。共有六种模式:
any(默认)
任何成功建立的连接都可接受。
read-write
会话必须默认接受读写事务(即服务不得处于热备模式,且 default_transaction_read_only 参数必须为 off)。
read-only
会话默认不得接受读写事务(与上一种模式相反)。
primary
服务不得处于热备模式。
standby
服务必须处于热备模式。
prefer-standby
先尝试查找备用服务;如果列出的主机中没有备用服务,则再次以 any 模式尝试。
load_balance_hosts #
控制客户端尝试连接可用主机和地址的顺序。连接尝试一旦成功,就不会再尝试其他主机和地址。此参数通常与多个主机名或返回多个 IP 地址的 DNS 记录搭配使用。此参数可以与 target_session_attrs 搭配使用,例如仅对备用服务进行负载均衡。成功连接后,返回的连接上的后续查询都会发送到同一服务。
目前有两种模式:
disable(默认)
不对主机进行负载均衡。按提供顺序尝试主机;按从 DNS 或 hosts 文件收到的顺序尝试地址。
random
以随机顺序尝试主机和地址。此值在同时打开多个连接时最有用,尤其是这些连接可能来自不同的机器时。这样可以将连接负载均衡到多个 PostgreSQL 服务上。由于随机负载均衡具有随机性,几乎不会产生完全均匀的分布,但从统计上看,分布会相当接近。
这里有一个重要方面:该算法会分两个层级进行随机选择。首先,按随机顺序解析主机;然后,在解析下一台主机之前,按随机顺序尝试当前主机解析出的所有地址。在某些情况下,例如某些主机解析出的地址比其他主机多,这种行为可能会大幅偏斜各节点获得的连接数量。但也可以有意利用这种偏斜,例如在 host 字符串中多次提供较大服务器的主机名,以增加它获得的连接数量。
使用此值时,建议同时为 connect_timeout 配置合理的值。这样,如果某个用于负载均衡的节点没有响应,就会尝试新节点。
oauth_issuer #
如果服务请求连接用的 OAuth 令牌,则用于联系受信任签发者的 HTTPS URL。所有 OAuth 连接都必须设置此参数;它必须与服务 HBA 配置中的 issuer 设置完全匹配。
作为标准身份验证握手的一部分,libpq 会向服务请求发现文档:一个提供一组 OAuth 配置参数的 URL。服务必须提供一个直接由 oauth_issuer 的各部分构造的 URL,并且此值必须与发现文档中声明的签发者标识符完全匹配,否则连接将失败。这是为了防止针对 OAuth 客户端的一类“混淆攻击”。
也可以显式将 oauth_issuer 设为 OAuth 发现使用的 /.well-known/ URI。如果服务请求不同的 URL,连接将失败;但自定义 OAuth 流程可能可以通过使用先前缓存的令牌来加快标准握手。(在这种情况下,建议同时设置 oauth_scope,因为客户端将没有机会向服务请求正确的 scope 设置,而令牌的默认 scope 可能不足以建立连接。)
libpq 目前支持以下众所周知的端点:
/.well-known/openid-configuration /.well-known/oauth-authorization-server
警告
在 OAuth 连接握手期间,签发者拥有高度权限。一般来说,如果不信任某个 URL 的运营者来处理对服务的访问权限,或直接冒充你,就不应将该 URL 作为 oauth_issuer 信任。
oauth_client_id #
授权服务签发的 OAuth 2.0 客户端标识符。如果 PostgreSQL 服务请求连接用的 OAuth 令牌(且未安装用于提供令牌的自定义 OAuth 钩子),则必须设置此参数;否则连接将失败。
oauth_client_secret #
联系 OAuth 授权服务时使用的客户端密码(如果有)。是否需要此参数取决于 OAuth 提供方;“公开”客户端通常不使用密码,而“机密”客户端通常会使用。
oauth_scope #
发送给授权服务的访问请求范围,以(可能为空的)OAuth scope 标识符空格分隔列表指定。此参数是可选的,供高级用法使用。通常,客户端会从 PostgreSQL 服务获取适当的 scope 设置。如果使用此参数,服务请求的 scope 列表将被忽略。这可以防止信任度较低的服务向最终用户请求不合适的访问 scope。
不过,如果客户端的 scope 设置不包含服务所要求的 scope,服务可能会拒绝发放的令牌,连接也会失败。空 scope 列表的含义取决于提供方。OAuth 授权服务可能会选择发放带有“默认 scope”的令牌(具体内容由其定义),也可能完全拒绝令牌请求。
PGconn
模式 2: 32.1.1. 连接字符串 # 多个 libpq 函数会解析用户指定的字符串,以获取连接参数。这些字符串支持两种格式:纯关键字/值字符串和 URI。URI 通常遵循 RFC 3986,但允许使用多个主机的连接字符串,具体说明如下。 32.1.1.1. 关键字/值连接字符串 # 在关键字/值格式中,每个参数设置的形式为 keyword = value,各设置之间用空格分隔。设置的等号两侧可以有空格,也可以没有。若要表示空值或包含空格的值,请用单引号括起来,例如 keyword = 'a value'。值中的单引号和反斜杠必须用反斜杠转义,即 ' 和 \。示例:host=localhost port=5432 dbname=mydb connect_timeout=10 可识别的参数关键字列于第 32.1.2 节。 32.1.1.2. 连接 URI # 连接 URI 的一般形式为: postgresql://[userspec@][hostspec][/dbname][?paramspec] 其中 userspec 为: user[:password],hostspec 为: [host][:port][,...],paramspec 为: name=value[&...] URI 方案标识符可以是 postgresql:// 或 postgres://。其余各 URI 部分均为可选项。以下示例展示了有效的 URI 语法: postgresql:// postgresql://localhost postgresql://localhost:5433 postgresql://localhost/mydb postgresql://user@localhost postgresql://user:secret@localhost postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp 通常会出现在 URI 层级部分的值,也可以改为通过命名参数指定。例如: postgresql:///mydb?host=localhost&port=5433 所有命名参数都必须与第 32.1.2 节列出的关键字匹配,但为兼容 JDBC 连接 URI,ssl=true 会被转换为 sslmode=require。若连接 URI 中包含其任何部分具有特殊含义的符号,则必须使用百分号编码。以下示例中,等号(=)替换为 %3D,空格替换为 %20: postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff 主机部分可以是主机名或 IP 地址。要指定 IPv6 地址,请将其括在方括号中: postgresql://[2001:db8::1234]/database 主机部分的解释方式与参数 host 的说明相同。特别是,如果主机部分为空或看起来像绝对路径名,则会选择 Unix 域套接字连接;否则会发起 TCP/IP 连接。但请注意,斜杠在 URI 的层级部分中是保留字符。因此,要指定非标准的 Unix 域套接字目录,可以省略 URI 的主机部分,并将主机指定为命名参数;也可以对 URI 主机部分中的路径进行百分号编码: postgresql:///dbname?host=/var/lib/postgresql postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 单个 URI 中可以指定多个主机部分,每个部分都可以包含可选的端口部分。形式为 postgresql://host1:port1,host2:port2,host3:port3/ 的 URI,等同于形式为 host=host1,host2,host3 port=port1,port2,port3 的连接字符串。如下文所述,系统会依次尝试每个主机,直到成功建立连接。 32.1.1.3. 指定多个主机 # 可以指定多个要连接的主机,系统会按给定顺序依次尝试。在关键字/值格式中,host、hostaddr 和 port 选项接受以逗号分隔的值列表。每个已指定选项中的元素数量必须相同;例如,第一个 hostaddr 对应第一个主机名,第二个 hostaddr 对应第二个主机名,依此类推。例外情况是,如果只指定一个 port,则该端口适用于所有主机。在连接 URI 格式中,可以在 URI 的主机部分列出多个以逗号分隔的 host:port 对。在这两种格式中,单个主机名都可能解析为多个网络地址。常见示例是同时具有 IPv4 和 IPv6 地址的主机。指定多个主机,或单个主机名解析为多个地址时,系统会按顺序尝试所有主机和地址,直到其中一个连接成功。如果无法连接到任何主机,则连接失败。如果已成功建立连接,但身份验证失败,则不会再尝试列表中的其余主机。如果使用密码文件,可以为不同的主机设置不同密码。列表中所有主机的其他连接选项都相同;例如,无法为不同主机指定不同的用户名。
keyword
模式 3: 示例:
host=localhost port=5432 dbname=mydb connect_timeout=10
模式 4: 32.1.1.2. 连接 URI # 连接 URI 的一般形式为:postgresql://[userspec@][hostspec][/dbname][?paramspec],其中 userspec 为:user[:password],hostspec 为:[host][:port][,...],paramspec 为:name=value[&...]。URI 方案标识符可以是 postgresql:// 或 postgres://。其余每个 URI 部分都是可选的。以下示例展示了有效的 URI 语法:postgresql:// postgresql://localhost postgresql://localhost:5433 postgresql://localhost/mydb postgresql://user@localhost postgresql://user:secret@localhost postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp 通常出现在 URI 层级部分中的值,也可以作为命名参数提供。例如:postgresql:///mydb?host=localhost&port=5433 所有命名参数都必须与第 32.1.2 节中列出的关键字匹配,但为兼容 JDBC 连接 URI,ssl=true 会被转换为 sslmode=require。如果连接 URI 包含在其任何部分中具有特殊含义的符号,则需要对其进行百分号编码。以下示例将等号(=)替换为 %3D,将空格替换为 %20:postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff 主机部分可以是主机名或 IP 地址。若要指定 IPv6 地址,请将其括在方括号中:postgresql://[2001:db8::1234]/database 主机部分的解释方式与参数 host 的说明相同。具体来说,如果主机部分为空或看起来像绝对路径名,则会选择 Unix 域套接字连接;否则会启动 TCP/IP 连接。不过请注意,斜杠是 URI 层级部分中的保留字符。因此,若要指定非标准的 Unix 域套接字目录,可以省略 URI 的主机部分并将主机指定为命名参数,或对 URI 主机部分中的路径进行百分号编码:postgresql:///dbname?host=/var/lib/postgresql postgresql://%2Fvar%2Flib%2Fpostgresql/dbname 单个 URI 中可以指定多个主机部分,每个部分都可以带有可选的端口部分。形式为 postgresql://host1:port1,host2:port2,host3:port3/ 的 URI,等价于形式为 host=host1,host2,host3 port=port1,port2,port3 的连接字符串。如下文所述,系统会依次尝试每个主机,直到成功建立连接。
postgresql://[userspec@][hostspec][/dbname][?paramspec]
where userspec is:
user[:password]
and hostspec is:
[host][:port][,...]
and paramspec is:
name=value[&...]
模式 5: 21.5. 预定义角色 # PostgreSQL 提供了一组预定义角色,可用于访问某些常见且需要特权的功能和信息。管理员(包括拥有 CREATEROLE 权限的角色)可以在其环境中将这些角色 GRANT 给用户和/或其他角色,从而使这些用户能够访问指定的功能和信息。例如:GRANT pg_signal_backend TO admin_user; 警告:授予这些角色时应谨慎,确保仅在需要时使用,并了解这些角色会授予对特权信息的访问权限。下面介绍这些预定义角色。请注意,随着新增功能,各角色的具体权限今后可能会发生变化。管理员应关注发行说明中的变更。pg_checkpoint # pg_checkpoint 允许执行 CHECKPOINT 命令。pg_create_subscription # pg_create_subscription 允许拥有数据库 CREATE 权限的用户执行 CREATE SUBSCRIPTION。pg_database_owner # pg_database_owner 始终且仅有一个隐式成员:当前数据库所有者。它不能被授予任何角色的成员资格,也不能将任何角色授予为 pg_database_owner 的成员。不过,与任何其他角色一样,它可以拥有对象并获得访问权限。因此,一旦 pg_database_owner 在模板数据库中拥有权限,从该模板实例化的每个数据库的所有者都会拥有这些权限。最初,此角色拥有 public 模式,因此每个数据库所有者都可以管理该模式在本地的使用。pg_maintain # pg_maintain 允许对所有关系执行 VACUUM、ANALYZE、CLUSTER、REFRESH MATERIALIZED VIEW、REINDEX 和 LOCK TABLE,效果等同于拥有这些对象的 MAINTAIN 权限。pg_monitorpg_read_all_settingspg_read_all_statspg_stat_scan_tables # 这些角色旨在让管理员能够轻松配置用于监控数据库服务器的角色。它们授予一组常见权限,使角色能够读取各种有用的配置设置、统计信息和其他通常仅限超级用户访问的系统信息。pg_monitor 允许读取/执行各种监控视图和函数。此角色是 pg_read_all_settings、pg_read_all_stats 和 pg_stat_scan_tables 的成员。pg_read_all_settings 允许读取所有配置变量,包括通常仅对超级用户可见的变量。pg_read_all_stats 允许读取所有 pg_stat_* 视图并使用各种统计信息相关扩展,包括通常仅对超级用户可见的内容。pg_stat_scan_tables 允许执行可能会对表获取 ACCESS SHARE 锁(且可能持续很长时间)的监控函数(例如,pgrowlocks 扩展中的 pgrowlocks(text))。pg_read_all_datapg_write_all_data # pg_read_all_data 允许读取所有数据(表、视图、序列),效果等同于对这些对象拥有 SELECT 权限,以及对所有模式拥有 USAGE 权限。此角色不会绕过行级安全(RLS)策略。如果使用了 RLS,管理员可以考虑对被授予此角色的角色设置 BYPASSRLS。pg_write_all_data 允许写入所有数据(表、视图、序列),效果等同于对这些对象拥有 INSERT、UPDATE 和 DELETE 权限,以及对所有模式拥有 USAGE 权限。此角色不会绕过行级安全(RLS)策略。如果使用了 RLS,管理员可以考虑对被授予此角色的角色设置 BYPASSRLS。pg_read_server_filespg_write_server_filespg_execute_server_program # 这些角色旨在让管理员拥有可信但非超级用户的角色,使其能够以运行数据库的用户身份访问数据库服务器上的文件并运行程序。它们在直接访问文件时会绕过所有数据库级权限检查,也可能被用于获取超级用户级别的访问权限。因此,向用户授予这些角色时应格外谨慎。pg_read_server_files 允许使用 COPY 和其他文件访问函数读取服务器上数据库可以访问的任意位置的文件。pg_write_server_files 允许使用 COPY 和其他文件访问函数写入服务器上数据库可以访问的任意位置的文件。pg_execute_server_program 允许使用 COPY 和其他可执行服务器端程序的函数,以运行数据库的用户身份在数据库服务器上执行程序。pg_signal_autovacuum_worker # pg_signal_autovacuum_worker 允许向 autovacuum 工作进程发送信号,以取消当前表的 vacuum 操作或终止其会话。请参见第 9.28.2 节。pg_signal_backend # pg_signal_backend 允许向其他后端发送信号,以取消查询或终止其会话。请注意,此角色不能向超级用户拥有的后端发送信号。请参见第 9.28.2 节。pg_use_reserved_connections # pg_use_reserved_connections 允许使用通过 reserved_connections 预留的连接槽。
CREATEROLE
模式 6: 6.4. 从已修改的行中返回数据 # 有时,在操作已修改的行时,获取这些行的数据会很有用。INSERT、UPDATE、DELETE 和 MERGE 命令都支持可选的 RETURNING 子句。使用 RETURNING 可以避免额外执行数据库查询来收集数据;如果难以可靠地识别已修改的行,这一功能尤其有价值。RETURNING 子句允许的内容与 SELECT 命令的输出列表相同(参见第 7.3 节)。它可以包含命令目标表的列名,也可以包含使用这些列的值表达式。常用的简写形式是 RETURNING *,它会按顺序选择目标表的所有列。在 INSERT 中,RETURNING 默认可用的数据是插入后的行。对于简单的插入,这不太有用,因为它只会重复客户端提供的数据。但如果依赖计算得出的默认值,这一功能就很方便。例如,使用 serial 列提供唯一标识符时,RETURNING 可以返回分配给新行的 ID:CREATE TABLE users (firstname text, lastname text, id serial primary key); INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id; RETURNING 子句对 INSERT ... SELECT 也很有用。在 UPDATE 中,RETURNING 默认可用的数据是已修改行的新内容。例如:UPDATE products SET price = price * 1.10 WHERE price <= 99.99 RETURNING name, price AS new_price; 在 DELETE 中,RETURNING 默认可用的数据是已删除行的内容。例如:DELETE FROM products WHERE obsoletion_date = 'today' RETURNING ; 在 MERGE 中,RETURNING 默认可用的数据是源行的内容,以及插入、更新或删除的目标行的内容。由于源表和目标表通常有许多相同的列,指定 RETURNING * 可能会导致大量重复列,因此通常最好限定它,只返回源行或目标行。例如:MERGE INTO products p USING new_products n ON p.product_no = n.product_no WHEN NOT MATCHED THEN INSERT VALUES (n.product_no, n.name, n.price) WHEN MATCHED THEN UPDATE SET name = n.name, price = n.price RETURNING p.; 在这些命令中,也可以明确返回已修改行的旧内容和新内容。例如:UPDATE products SET price = price * 1.10 WHERE price <= 99.99 RETURNING name, old.price AS old_price, new.price AS new_price, new.price - old.price AS price_change; 在此示例中,写 new.price 与只写 price 相同,但前者能更清楚地表达含义。INSERT、UPDATE、DELETE 和 MERGE 命令都支持这种返回旧值和新值的语法,但对于 INSERT,旧值通常为 NULL;对于 DELETE,新值通常为 NULL。不过,在某些情况下,这种语法对这些命令仍然有用。例如,在带有 ON CONFLICT DO UPDATE 子句的 INSERT 中,冲突行的旧值将为非 NULL。同样,如果 DELETE 通过重写规则转换为 UPDATE,新值可能为非 NULL。如果目标表上有触发器(第 37 章),RETURNING 可用的数据就是触发器修改后的行。因此,检查由触发器计算的列也是 RETURNING 的常见用途之一。
INSERT
模式 7: 在 UPDATE 中,RETURNING 默认可用的数据是已修改行的新内容。例如:
UPDATE
模式 8: 在 DELETE 中,RETURNING 默认可用的数据是已删除行的内容。例如:
DELETE
示例代码模式
示例 1(javascript):
PGconn *PQconnectdbParams(const char * const *keywords,
const char * const *values,
int expand_dbname);
示例 2(javascript):
PGconn *PQconnectdb(const char *conninfo);
参考文件
此技能包含 references/ 中的完整文档:
- getting_started.md - 入门文档
- sql.md - Sql 文档
需要详细信息时,使用 view 阅读特定参考文件。
使用此技能
初学者
从入门或教程参考文件开始,了解基础概念。
了解特定功能
使用相应类别的参考文件(api、guides 等)了解详细信息。
查看代码示例
上方的快速参考部分包含从官方文档中提取的常见模式。
资源
references/
整理了从官方来源提取的文档。这些文件包含:
- 详细说明
- 带语言注释的代码示例
- 原始文档链接
- 便于快速导航的目录
scripts/
在此处添加用于常见自动化任务的辅助脚本。
assets/
在此处添加模板、样板文件或示例项目。
注意事项
- 此技能由官方文档自动生成
- 参考文件保留了源文档的结构和示例
- 代码示例包含语言检测信息,以便更好地进行语法高亮
- 快速参考模式从文档中的常见用法示例提取
更新
要使用更新后的文档刷新此技能:
- 使用相同的配置重新运行抓取程序
- 技能将使用最新信息重新构建