34.1. 数据库连接控制函数#
以下函数用于连接到PostgreSQL后端服务器。应用程序可以同时打开多个后端连接。(这样做的一个原因是访问多个数据库。)每个连接都由PGconn
对象表示,该对象可从函数PQconnectdb
、PQconnectdbParams
或PQsetdbLogin
获取。请注意,除非内存不足以分配PGconn
对象,否则这些函数始终会返回一个非空对象指针。PQstatus
函数应在通过连接对象发送查询之前被调用,以检查返回的值是否为成功连接。
警告
如果不受信任的用户有权访问尚未采用安全模式使用模式的数据库,请在每次会话开始时从search_path
中删除可公开写入的模式。可以将参数关键字options
设置为值-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
)。当前识别的参数关键字列在 第 34.1.2 节 中。
传递的数组可以为空,以使用所有默认参数,或者可以包含一个或多个参数设置。它们必须在长度上匹配。处理将在
NULL
数组中的第一个keywords
条目处停止。此外,如果与非NULL
keywords
条目关联的values
条目为NULL
或空字符串,则该条目将被忽略,并且处理将继续进行下一对数组条目。当
expand_dbname
非零时,将检查第一个dbname
关键字的值,以查看它是否为 连接字符串。如果是,则它将 “展开” 到从字符串中提取的各个连接参数。如果值包含等号 (=
) 或以 URI 方案设计器开头,则该值被认为是连接字符串,而不仅仅是数据库名称。(有关连接字符串格式的更多详细信息,请参见 第 34.1.1 节。)只有第一个出现的dbname
以这种方式处理;任何后续的dbname
参数都将作为普通数据库名称进行处理。通常,参数数组从头到尾处理。如果重复任何关键字,则使用最后一个值(不是
NULL
或空)。此规则尤其适用于连接字符串中找到的关键字与keywords
数组中出现的关键字冲突的情况。因此,程序员可以确定数组条目是否可以覆盖或被从连接字符串获取的值覆盖。在展开的dbname
条目之前出现的数组条目可以被连接字符串的字段覆盖,而这些字段又会被dbname
之后出现的数组条目覆盖(但同样,仅当这些条目提供非空值时)。在处理所有数组条目和任何展开的连接字符串后,将用默认值填充所有仍未设置的连接参数。如果未设置的参数的相应环境变量(请参见 第 34.15 节)已设置,则使用其值。如果环境变量也没有设置,则使用参数的内置默认值。
PQconnectdb
#建立与数据库服务器的新连接。
PGconn *PQconnectdb(const char *conninfo);
此函数使用从字符串
conninfo
中获取的参数打开一个新的数据库连接。传递的字符串可以为空以使用所有默认参数,或者可以包含一个或多个由空格分隔的参数设置,或者可以包含一个 。有关详细信息,请参见 第 34.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
包含=
符号或具有有效的连接 前缀,则它将被视为conninfo
字符串,就像将其传递给PQconnectdb
一样,然后按照为PQconnectdbParams
指定的方式应用剩余参数。pgtty
不再使用,并且将忽略传递的任何值。PQsetdb
#建立与数据库服务器的新连接。
PGconn *PQsetdb(char *pghost, char *pgport, char *pgoptions, char *pgtty, char *dbName);
这是一个宏,它使用空指针调用
PQsetdbLogin
作为login
和pwd
参数。它提供向后兼容性,适用于非常旧的程序。PQconnectStartParams
PQconnectStart
PQconnectPoll
#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 查询。有关此参数的文档,请参阅 第 34.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()
或类似系统函数所指示)。然后再次调用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
的返回值中,可以同样检测到这两种状态。在异步连接过程中(并且仅在异步连接过程中),还可能出现其他状态。这些状态指示连接过程的当前阶段,并且可能有助于向用户提供反馈,例如。这些状态是请注意,尽管这些常量将保持不变(为了保持兼容性),但应用程序绝不应依赖于这些常量以特定顺序(或根本不出现)或状态始终是这些记录值之一。应用程序可以执行类似以下操作
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
,以便处理结构和任何关联的内存块。即使连接尝试失败或被放弃,也必须执行此操作。PQconndefaults
#返回默认连接选项。
PQconninfoOption *PQconndefaults(void);
typedef struct { char keyword; / The keyword of the option */ char envvar; / Fallback environment variable name */ char compiled; / Fallback compiled in default value */ char val; / Option's current value, or NULL */ char label; / Label for field in connect dialog / char dispchar; / Indicates how to display this field in a connect dialog. Values are: "" Display entered value as is "" Password field - hide value "D" Debug option - don't show by default / int dispsize; / Field size in characters for dialog */ } PQconninfoOption;
返回连接选项数组。这可用于确定所有可能的
PQconnectdb
选项及其当前默认值。返回值指向PQconninfoOption
结构的数组,该数组以具有空keyword
指针的条目结束。如果无法分配内存,则返回空指针。请注意,当前默认值(val
字段)将取决于环境变量和其他上下文。将忽略缺失或无效的服务文件。调用方必须将连接选项数据视为只读。处理选项数组后,通过将其传递给
PQconninfoFree
来释放它。如果不这样做,则每次调用PQconndefaults
都会泄漏少量内存。PQconninfo
#返回活动连接使用的连接选项。
PQconninfoOption *PQconninfo(PGconn *conn);
返回连接选项数组。这可用于确定所有可能的
PQconnectdb
选项以及用于连接到服务器的值。返回值指向PQconninfoOption
结构的数组,该数组以具有空keyword
指针的条目结束。上面PQconndefaults
的所有注释也适用于PQconninfo
的结果。PQconninfoParse
#从提供的连接字符串返回已解析的连接选项。
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
解析连接字符串并将结果选项作为数组返回;或在连接字符串有问题时返回
NULL
。此函数可用于提取提供的连接字符串中的PQconnectdb
选项。返回值指向PQconninfoOption
结构的数组,该数组以具有空keyword
指针的条目结束。所有合法选项都将出现在结果数组中,但连接字符串中不存在的任何选项的
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);
此函数将关闭与服务器的连接,并尝试使用先前使用的所有相同参数建立新连接。如果工作连接丢失,这可能对错误恢复有用。
PQresetStart
PQresetPoll
#以非阻塞方式重置与服务器的通信通道。
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
#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);
34.1.1. 连接字符串#
多个libpq函数解析用户指定字符串以获取连接参数。这些字符串有两种可接受的格式:纯关键字/值字符串和 URI。URI 通常遵循RFC 3986,但允许多主机连接字符串,如下文所述。
34.1.1.1. 关键字/值连接字符串#
在关键字/值格式中,每个参数设置都采用*关键字
=
值
*的形式,设置之间用空格分隔。设置等号周围的空格是可选的。要编写空值或包含空格的值,请用单引号将其引起来,例如keyword = 'a value'
。值中的单引号和反斜杠必须用反斜杠转义,即\'
和\\
。
示例
host=localhost port=5432 dbname=mydb connect_timeout=10
已识别的参数关键字列在第 34.1.2 节中。
34.1.1.2. 连接 URI#
连接URI的一般形式为
postgresql://[userspec@][hostspec][/dbname][?paramspec]
where userspec is:
user[:password]
and hostspec is:
[host][:port][,...]
and paramspec is:
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
所有命名参数都必须与第 34.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
的连接字符串。如下文所述,每个主机将被依次尝试,直到成功建立连接。
34.1.1.3. 指定多个主机#
可以指定多个要连接的主机,以便按给定顺序尝试这些主机。在关键字/值格式中,host
、hostaddr
和port
选项接受用逗号分隔的值列表。在指定的每个选项中必须给出相同数量的元素,例如,第一个hostaddr
对应于第一个主机名,第二个hostaddr
对应于第二个主机名,依此类推。作为一个例外,如果只指定了一个port
,则它适用于所有主机。
在连接 URI 格式中,可以在 URI 的host
组件中列出多个用逗号分隔的host:port
对。
在任一格式中,单个主机名都可以转换为多个网络地址。一个常见的示例是同时具有 IPv4 和 IPv6 地址的主机。
当指定多个主机或将单个主机名转换为多个地址时,将按顺序尝试所有主机和地址,直到其中一个成功。如果无法访问任何主机,则连接失败。如果成功建立连接,但身份验证失败,则不会尝试列表中剩余的主机。
如果使用密码文件,则可以为不同的主机设置不同的密码。列表中每个主机的其他所有连接选项都是相同的;例如,无法为不同的主机指定不同的用户名。
34.1.2. 参数关键字#
当前识别的参数关键字为
host
#要连接到的主机的名称。如果主机名看起来像绝对路径名,则它指定 Unix 域通信而不是 TCP/IP 通信;该值是存储套接字文件的目录的名称。(在 Unix 中,绝对路径名以斜杠开头。在 Windows 中,也识别以驱动器字母开头的路径。)如果主机名以
@
开头,则将其视为抽象名称空间中的 Unix 域套接字(目前在 Linux 和 Windows 上受支持)。当未指定host
或其为空时,默认行为是连接到/tmp
(或在构建 PostgreSQL 时指定的任何套接字目录)中的 Unix 域套接字。在 Windows 中,默认行为是连接到localhost
。同样接受以逗号分隔的主机名列表,在这种情况下,列表中的每个主机名按顺序尝试;列表中的空项选择如上所述的默认行为。有关详细信息,请参见第 34.1.1.3 节。
hostaddr
#要连接到的主机的数字 IP 地址。这应采用标准 IPv4 地址格式,例如
172.28.40.9
。如果您的机器支持 IPv6,您还可以使用这些地址。当为此参数指定非空字符串时,总是使用 TCP/IP 通信。如果未指定此参数,将查找host
的值以找到相应的 IP 地址——或者,如果host
指定 IP 地址,则该值将直接使用。使用
hostaddr
允许应用程序避免主机名查找,这对于有时间限制的应用程序可能很重要。但是,GSSAPI 或 SSPI 身份验证方法以及verify-full
SSL 证书验证需要主机名。使用以下规则如果未指定
hostaddr
而指定了host
,则会发生主机名查找。(使用PQconnectPoll
时,查找发生在PQconnectPoll
首次考虑此主机名时,并且可能导致PQconnectPoll
阻塞大量时间。)如果未指定
host
而指定了hostaddr
,则hostaddr
的值提供了服务器网络地址。如果身份验证方法需要主机名,则连接尝试将失败。如果同时指定了
host
和hostaddr
,则hostaddr
的值提供了服务器网络地址。除非身份验证方法需要它,否则将忽略host
的值,在这种情况下,它将用作主机名。
请注意,如果
host
不是网络地址hostaddr
处的服务器名称,则身份验证可能会失败。此外,当同时指定host
和hostaddr
时,host
用于在密码文件中识别连接(请参见第 34.16 节)。还可以接受一个以逗号分隔的
hostaddr
值列表,在这种情况下,将按列表中的顺序尝试每个主机。列表中的空项将导致使用相应的主机名,如果该主机名也为空,则使用默认主机名。有关详细信息,请参见 第 34.1.1.3 节。如果没有主机名或主机地址,libpq 将使用本地 Unix 域套接字进行连接;或者在 Windows 上,它将尝试连接到
localhost
。port
#在服务器主机上连接到的端口号,或 Unix 域连接的套接字文件扩展名。 如果在
host
或hostaddr
参数中给出了多个主机,则此参数可以指定一个与主机列表长度相同的以逗号分隔的端口列表,或者可以指定一个用于所有主机的端口号。一个空字符串或一个以逗号分隔的列表中的一个空项指定了在构建 PostgreSQL 时建立的默认端口号。dbname
#数据库名称。默认为与用户名相同。在某些情况下,将检查值是否为扩展格式;有关这些格式的更多详细信息,请参见 第 34.1.1 节。
user
#要以其身份连接的 PostgreSQL 用户名。默认为运行该应用程序的用户的操作系统名称。
password
#如果服务器要求密码身份验证,则要使用的密码。
passfile
#指定用于存储密码的文件的名称(请参见 第 34.16 节)。默认为
~/.pgpass
,或在 Microsoft Windows 上为%APPDATA%\postgresql\pgpass.conf
。(如果此文件不存在,则不报告错误。)require_auth
#指定客户端要求服务器使用的认证方法。如果服务器不使用所需方法来认证客户端,或如果认证握手未由服务器完全完成,连接将会失败。还可以提供一个方法的逗号分隔列表,服务器必须在其中准确使用一个方法才能使连接成功。默认情况下,接受任何认证方法,服务器可以完全跳过认证。
可以通过添加
!
前缀来否定方法,在这种情况下,服务器必须不尝试列出的方法;接受任何其他方法,服务器可以完全不认证客户端。如果提供了逗号分隔列表,服务器可能不会尝试任何列出的否定方法。否定形式和非否定形式不能在同一设置中组合。作为最后一种特殊情况,
none
方法要求服务器不使用认证质询。(它也可以被否定,以要求某种形式的认证。)可以指定以下方法
password
服务器必须请求明文密码认证。
md5
服务器必须请求 MD5 哈希密码认证。
gss
服务器必须通过 请求 Kerberos 握手或建立 加密通道(另请参见 gssencmode)。
sspi
服务器必须请求 Windows 认证。
scram-sha-256
服务器必须与客户端成功完成 SCRAM-SHA-256 认证交换。
none
服务器不得提示客户端进行认证交换。(这并不禁止通过 TLS 进行客户端证书认证,也不禁止通过其加密传输进行 GSS 认证。)
channel_binding
#此选项控制客户端使用通道绑定的方式。设置
require
表示连接必须使用通道绑定,prefer
表示客户端将在可用时选择通道绑定,disable
阻止使用通道绑定。如果使用 SSL 支持编译 PostgreSQL,则默认值为prefer
;否则,默认值为disable
。通道绑定是服务器对自身进行客户端认证的一种方法。它仅在使用
SCRAM
认证方法的 PostgreSQL 11 或更高版本服务器的 SSL 连接上受支持。connect_timeout
#以秒为单位,连接时等待的最长时间(写为十进制整数,例如
10
)。零、负数或未指定表示无限期等待。允许的最小超时时间为 2 秒,因此1
的值将解释为2
。此超时时间分别适用于每个主机名或 IP 地址。例如,如果您指定两个主机且connect_timeout
为 5,则如果在 5 秒内未建立连接,每个主机都会超时,因此等待连接所花费的总时间可能长达 10 秒。client_encoding
#这将为该连接设置
client_encoding
配置参数。除了相应服务器选项接受的值之外,您还可以使用auto
从客户端中的当前区域设置(Unix 系统上的LC_CTYPE
环境变量)确定正确的编码。options
#指定在连接启动时发送到服务器的命令行选项。例如,将此选项设置为
-c geqo=off
会将geqo
参数的会话值设置为off
。此字符串中的空格被视为分隔命令行参数,除非使用反斜杠 (\
) 转义;编写\\
以表示一个实际的反斜杠。有关可用选项的详细讨论,请参阅 第 20 章。application_name
#为 application_name 配置参数指定一个值。
fallback_application_name
#为 application_name 配置参数指定一个后备值。如果未通过连接参数或
PGAPPNAME
环境变量为application_name
给出值,则将使用此值。在希望设置默认应用程序名称但允许用户覆盖该名称的通用实用程序中,指定后备名称非常有用。keepalives
#控制是否使用客户端 TCP 保活。默认值为 1,表示启用,但如果不需要保活,可以将此值更改为 0,表示禁用。对于通过 Unix 域套接字建立的连接,此参数将被忽略。
keepalives_idle
#控制在 TCP 向服务器发送保活消息之前的不活动秒数。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接或禁用保活时,此参数将被忽略。它仅在
TCP_KEEPIDLE
或等效套接字选项可用的系统和 Windows 上受支持;在其他系统上,它不起作用。keepalives_interval
#控制在服务器未确认 TCP 保活消息后重新传输该消息的秒数。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接或禁用保活时,此参数将被忽略。它仅在
TCP_KEEPINTVL
或等效套接字选项可用的系统和 Windows 上受支持;在其他系统上,它不起作用。keepalives_count
#控制在客户端与服务器的连接被视为死亡之前可以丢失的 TCP 保活数。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接或禁用保活时,此参数将被忽略。它仅在
TCP_KEEPCNT
或等效套接字选项可用的系统上受支持;在其他系统上,它不起作用。tcp_user_timeout
#控制在强制关闭连接之前,已传输的数据可以保持未确认状态的毫秒数。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,此参数将被忽略。它仅在
TCP_USER_TIMEOUT
可用的系统上受支持;在其他系统上,它不起作用。replication
#此选项确定连接是否应该使用复制协议而不是普通协议。这是 PostgreSQL 复制连接以及 pg_basebackup 等工具在内部使用的,但也可以由第三方应用程序使用。有关复制协议的说明,请参阅 第 55.4 节。
支持以下不区分大小写的值
true
、on
、yes
、1
连接进入物理复制模式。
database
连接进入逻辑复制模式,连接到
dbname
参数中指定的数据库。false
、off
、no
、0
连接是常规连接,这是默认行为。
在物理或逻辑复制模式下,只能使用简单查询协议。
gssencmode
#此选项确定是否以及以何种优先级与服务器协商安全的 TCP/IP 连接。有三种模式
disable
仅尝试非 加密的连接
prefer
(默认)如果存在 凭据(即在凭据缓存中),则首先尝试 加密的连接;如果失败或没有凭据,则尝试非 加密的连接。这是在 PostgreSQL 已使用 支持编译时的默认设置。
require
仅尝试 加密的连接
对于 Unix 域套接字通信,
gssencmode
被忽略。如果 PostgreSQL 在没有 GSSAPI 支持的情况下编译,则使用require
选项将导致错误,而prefer
将被接受,但 libpq 实际上不会尝试 加密的连接。sslmode
#此选项确定是否以及以何种优先级与服务器协商安全的 TCP/IP 连接。有六种模式
disable
仅尝试非 连接
allow
首先尝试非 连接;如果失败,则尝试 连接
prefer
(默认)首先尝试 连接;如果失败,则尝试非 连接
require
仅尝试 连接。如果存在根 CA 文件,则以与指定
verify-ca
相同的方式验证证书verify-ca
仅尝试 连接,并验证服务器证书是由受信任的证书颁发机构 () 颁发的
verify-full
仅尝试 连接,验证服务器证书是由受信任的 颁发的,并且请求的服务器主机名与证书中的主机名相匹配
有关这些选项如何工作的详细说明,请参见 第 34.19 节。
对于 Unix 域套接字通信,
sslmode
将被忽略。如果 PostgreSQL 在没有 SSL 支持的情况下编译,则使用选项require
、verify-ca
或verify-full
将导致错误,而选项allow
和prefer
将被接受,但 libpq 实际上不会尝试 连接。请注意,如果 加密是可行的,那么将优先使用它而不是 加密,而不管
sslmode
的值如何。要在具有可用的 基础架构(例如 Kerberos 服务器)的环境中强制使用 加密,还应将gssencmode
设置为disable
。requiressl
#此选项已弃用,取而代之的是
sslmode
设置。如果设置为 1,则需要与服务器建立 连接(这等效于
sslmode
require
)。如果服务器不接受 连接,libpq 将拒绝连接。如果设置为 0(默认值),libpq 将与服务器协商连接类型(等效于sslmode
prefer
)。仅当 PostgreSQL 在具有 SSL 支持的情况下编译时,此选项才可用。sslcompression
#如果设置为 1,则通过 SSL 连接发送的数据将被压缩。如果设置为 0,则将禁用压缩。默认值为 0。如果建立了无 SSL 的连接,则将忽略此参数。
如今,SSL 压缩被认为不安全,不再建议使用。默认情况下,OpenSSL 1.1.0 禁用压缩,许多操作系统发行版也在早期版本中禁用了压缩,因此如果服务器不接受压缩,则将此参数设置为开将不会产生任何效果。PostgreSQL 14 在后端完全禁用了压缩。
如果安全性不是主要问题,则如果网络是瓶颈,压缩可以提高吞吐量。如果 CPU 性能是限制因素,则禁用压缩可以提高响应时间和吞吐量。
sslcert
#此参数指定客户端 SSL 证书的文件名,替换默认的
~/.postgresql/postgresql.crt
。如果未建立 SSL 连接,则将忽略此参数。sslkey
#此参数指定用于客户端证书的密钥的位置。它可以指定一个文件名,该文件名将代替默认的
~/.postgresql/postgresql.key
,或者它可以指定从外部“引擎”获取的密钥(引擎是OpenSSL可加载模块)。外部引擎规范应由冒号分隔的引擎名称和特定于引擎的密钥标识符组成。如果未建立 SSL 连接,则将忽略此参数。sslpassword
#此参数指定
sslkey
中指定的密钥的密码,允许将客户端证书私钥以加密形式存储在磁盘上,即使交互式密码输入不切实际也是如此。使用任何非空值指定此参数将禁止
Enter PEM pass phrase:
提示,当向libpq
提供加密的客户端证书密钥时,OpenSSL默认会发出该提示。如果密钥未加密,则将忽略此参数。该参数对由OpenSSL引擎指定的密钥没有影响,除非引擎对提示使用OpenSSL密码回调机制。
没有与此选项等效的环境变量,也没有在
.pgpass
中查找它的工具。它可以在服务文件连接定义中使用。具有更复杂用途的用户应考虑使用OpenSSL引擎和诸如 PKCS#11 或 USB 加密卸载设备之类的工具。sslcertmode
#此选项确定是否可以向服务器发送客户端证书,以及是否要求服务器请求客户端证书。有三种模式
disable
即使有客户端证书(默认位置或通过 sslcert 提供),也绝不会发送客户端证书。
allow
(默认)如果服务器请求证书且客户端有证书可发送,则可以发送证书。
require
服务器必须请求证书。如果客户端不发送证书,而服务器成功验证了客户端,则连接将失败。
注意
sslcertmode=require
不会增加任何额外的安全性,因为无法保证服务器正确验证证书;PostgreSQL 服务器通常会从客户端请求 TLS 证书,无论它们是否验证这些证书。在对更复杂的 TLS 设置进行故障排除时,此选项可能有用。sslrootcert
#此参数指定包含 SSL 证书颁发机构 () 证书的文件的名称。如果文件存在,则服务器的证书将被验证为由其中一个颁发机构签名。默认值为
~/.postgresql/root.crt
。可以指定特殊值
system
,在这种情况下,将加载系统的受信任 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 扩展 “服务器名称指示” ()。将此参数设置为 0,则会关闭此功能。
SSL 感知代理可以使用服务器名称指示来路由连接,而无需解密 SSL 流。(请注意,这需要一个了解 PostgreSQL 协议握手过程的代理,而不仅仅是任何 SSL 代理。)但是, 会使目标主机名以明文形式显示在网络流量中,因此在某些情况下可能不希望使用。
requirepeer
#此参数指定服务器的操作系统用户名,例如
requirepeer=postgres
。在建立 Unix 域套接字连接时,如果设置了此参数,则客户端会在连接开始时检查服务器进程是否在指定用户名下运行;如果不是,则连接会因错误而中止。此参数可用于提供与 TCP/IP 连接上的 SSL 证书类似的服务器身份验证。(请注意,如果 Unix 域套接字位于/tmp
或其他可公开写入的位置,则任何用户都可以启动在该位置侦听的服务器。使用此参数可确保连接到由受信任用户运行的服务器。)此选项仅在实现了peer
身份验证方法的平台上受支持;请参阅第 21.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 的版本,较旧的版本不支持最新的协议版本。如果未设置,则忽略此参数,并且连接将使用后端定义的最大绑定(如果已设置)。设置最大协议版本主要用于测试,或者如果某个组件在使用较新协议时出现问题。krbsrvname
#使用 GSSAPI 认证时的 Kerberos 服务名称。此名称必须与 Kerberos 认证的服务器配置中指定的服务名称相匹配,才能成功进行认证。(另请参见 第 21.6 节。)默认值通常为
postgres
,但在通过 configure 的--with-krb-srvnam
选项构建 PostgreSQL 时可以更改此值。在大多数环境中,此参数永远不需要更改。某些 Kerberos 实现可能需要不同的服务名称,例如 Microsoft Active Directory,它要求服务名称为大写 (POSTGRES
)。gsslib
#用于 GSSAPI 认证的 GSS 库。目前,除了同时包含 GSSAPI 和 SSPI 支持的 Windows 版本外,此项均被忽略。在这种情况下,将其设置为
gssapi
以使 libpq 使用 GSSAPI 库进行认证,而不是默认的 SSPI。gssdelegation
#将 GSS 凭据转发(委托)到服务器。默认值为
0
,表示不会将凭据转发到服务器。将其设置为1
以在可能的情况下转发凭据。service
#用于其他参数的服务名称。它指定
pg_service.conf
中包含其他连接参数的服务名称。这允许应用程序仅指定服务名称,以便可以集中维护连接参数。请参阅 第 34.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 或主机文件接收的顺序尝试。
random
主机和地址按随机顺序尝试。此值在同时打开多个连接时非常有用,可能来自不同的机器。这样,可以在多个 PostgreSQL 服务器之间进行负载平衡。
虽然随机负载平衡由于其随机性几乎永远不会导致完全均匀的分布,但从统计学上来说它非常接近。这里的一个重要方面是,此算法使用两级随机选择:首先,主机将按随机顺序解析。然后,在解析下一个主机之前,将按随机顺序尝试当前主机的所有已解析地址。在某些情况下,此行为可能会极大地影响每个节点获得的连接数,例如,当某些主机解析为比其他主机更多的地址时。但这种偏差也可以有目的地使用,例如,通过在主机字符串中多次提供其主机名来增加较大的服务器获得的连接数。
使用此值时,建议也为 connect_timeout 配置合理的值。因为那时,如果用于负载平衡的某个节点没有响应,将尝试一个新节点。