pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
目录
libpq是PostgreSQL的C应用程序编程接口。libpq是一组库函数,客户端程序可用它们向PostgreSQL后端服务器发送查询并接收查询结果。
libpq也是其他几个PostgreSQL应用程序接口的底层引擎,包括为 C++、Perl、Python、Tcl 和ECPG编写的接口。因此,对于这些包的用户,libpq行为的某些方面也很重要。特别是,第 31.13 节、第 31.14 节和第 31.17 节描述了任何使用libpq的应用程序的用户都能观察到的行为。
本章末尾(第 31.20 节)包含一些简短程序,展示如何编写使用libpq的程序。源代码发行包的src/test/examples目录中还提供了几个完整的libpq应用程序示例。
使用libpq的客户端程序必须包含头文件libpq-fe.h,并且必须与libpq库链接。
下列函数处理与PostgreSQL后端服务器建立连接。一个应用可以同时打开多个后端连接。(这样做的一个原因是访问多个数据库。)每个连接由一个PGconn对象表示,该对象从函数PQconnectdb、PQconnectdbParams或PQsetdbLogin获得。注意,除非可能连分配PGconn对象的内存都不够,这些函数将总是返回一个非空的对象指针。在通过连接对象发送查询之前,应该调用PQstatus函数检查连接是否已成功建立。
在 Unix 上,fork 一个带有打开的 libpq 连接的进程可能导致不可预测的结果,因为父进程和子进程共享相同的套接字和操作系统资源。因此不推荐这种用法,不过在子进程中执行exec来载入新的可执行文件是安全的。
在 Windows 上,如果单个数据库连接被反复地启动和关闭,有一种办法可以改进性能。在内部, libpq 分别调用 WSAStartup() 和 WSACleanup() 来启动和关闭连接。WSAStartup() 会增加一个内部 Windows 库引用计数, 而 WSACleanup() 会递减该计数。当引用计数恰好为 1 时,调用 WSACleanup() 会释放所有资源并卸载所有 DLL。这是一项代价很高的 操作。为避免这种情况,应用程序可以手工调用 WSAStartup(), 这样在最后一个数据库连接关闭时资源就不会被释放。
PQconnectdbParams #开启一个到数据库服务器的新连接。
PGconn *PQconnectdbParams(const char **keywords, const char **values, int expand_dbname);
这个函数使用从两个以NULL结尾的数组中取得的参数打开一个新的数据库连接。第一个数组keywords是一个字符串数组,其中每个元素都是一个关键词。第二个数组values给出每个关键词的值。和下面的PQsetdbLogin不同,参数集合可以在不改变函数签名的情况下扩展,因此对于新应用,最好使用这个函数(或者相应的非阻塞函数PQconnectStartParams和PQconnectPoll)。
当 expand_dbname 非零时,允许把dbname关键词的值识别为一个conninfo字符串。详见下文。
传入的数组可以为空以使用全部默认参数,也可以包含一个或多个参数设置。两个数组的长度应当相同。处理会随着keywords数组的最后一个非NULL元素而停止。
当前识别的参数关键字如下:
host #要连接的主机名。如果主机名以斜杠开头,则指定的是 Unix 域通信,而非 TCP/IP 通信;此值是存放套接字文件的目录名。当未指定 host 或其值为空时,默认连接到 /tmp(或构建 PostgreSQL 时指定的套接字目录)中的 Unix 域套接字。在没有 Unix 域套接字的机器上,默认连接到 localhost。
hostaddr #要连接的主机的数字 IP 地址。应采用标准的 IPv4 地址格式,例如 172.28.40.9。如果机器支持 IPv6,也可以使用 IPv6 地址。只要此参数指定了非空字符串,就始终使用 TCP/IP 通信。
使用hostaddr而非host让应用可以避免一次主机名查找,这对于有时间约束的应用可能很重要。不过,Kerberos、GSSAPI 或 SSPI 认证以及完整的 SSL 证书验证都需要主机名。使用的规则如下:如果指定了host而没有指定hostaddr,会发生一次主机名查找。如果指定了hostaddr而没有指定host,则hostaddr的值给出服务器地址。在需要主机名的任何情况下,连接尝试都会失败。如果同时指定了host和hostaddr,则hostaddr的值给出服务器地址,而host的值会被忽略,除非认证或验证目的需要它,此时它会作为主机名使用。注意,如果host不是位于hostaddr的那台机器的名字,认证很可能会失败。另外注意,在~/.pgpass中是用host而不是hostaddr来标识连接的(见第 31.14 节)。
如果既没有主机名也没有主机地址,libpq 会使用本地 Unix 域套接字连接;在没有 Unix 域套接字的机器上,则会尝试连接到 localhost。
port #dbname #数据库名称。默认为与用户名相同。
user #建立连接所用的 PostgreSQL 用户名。默认与运行应用程序的操作系统用户名相同。
password #服务器要求密码认证时所使用的密码。
connect_timeout #连接时的最长等待时间,以秒为单位(写成十进制整数字符串)。 零或未指定表示无限等待。不建议使用小于2秒的超时时间。
options #添加在运行时发送给服务器的命令行选项。例如,将其设置为-c geqo=off会把会话的geqo参数值设为off。 有关可用选项的详细讨论,请参阅第 18 章。
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 或 TCP_KEEPALIVE 套接字选项的系统以及 Windows 上受支持;在其他系统上无效。
keepalives_interval #控制未被服务器确认收到的 TCP keepalive 消息在多少秒后应被重传。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,或禁用 keepalive 时,此参数会被忽略。此参数仅在支持 TCP_KEEPINTVL 套接字选项的系统以及 Windows 上受支持;在其他系统上无效。
keepalives_count #控制在客户端与服务器之间的连接被视为中断之前,可以丢失多少个 TCP keepalive 消息。值为零时使用系统默认值。对于通过 Unix 域套接字建立的连接,或禁用 keepalive 时,此参数会被忽略。此参数仅在支持 TCP_KEEPCNT 套接字选项的系统上受支持;在其他系统上无效。
tty #忽略此参数(以前用于指定服务器调试输出的发送位置)。
sslmode #这个选项决定是否或以何种优先级与服务器协商一个安全的SSL TCP/IP 连接。有六种模式:
表 31.1. sslmode 选项
| 选项 | 描述 |
|---|---|
disable |
仅尝试非SSL连接 |
allow |
首先尝试非SSL连接;如果失败,则尝试SSL连接 |
prefer(默认) |
首先尝试SSL连接;如果失败,则尝试非SSL连接 |
require |
仅尝试SSL连接。如果存在根 CA 文件,则验证证书的方式与指定了verify-ca时相同 |
verify-ca |
仅尝试SSL连接,并验证服务器证书是由一个受信任的CA颁发的 |
verify-full |
仅尝试SSL连接,验证服务器证书是由一个受信任的CA颁发的,并且服务器主机名与证书中的相匹配 |
关于这些选项如何工作的详细描述见第 31.17 节。
在 Unix 域套接字通信中,sslmode 会被忽略。 如果PostgreSQL编译时未启用 SSL 支持, 使用选项require、verify-ca或 verify-full会导致错误,而选项allow和prefer 将被接受,但libpq实际上不会尝试建立SSL 连接。
requiressl #此选项已弃用,请改用 sslmode 设置。
如果设置为1,则需要与服务器建立SSL连接(这相当于sslmode require)。libpq将拒绝连接,如果服务器不接受 SSL连接。如果设置为0(默认值), libpq将与服务器协商连接类型(相当于sslmode prefer)。此选项仅在 PostgreSQL 编译时启用了 SSL 支持的情况下可用。
sslcert #这个参数指定客户端SSL证书的文件名,替换默认的 ~/.postgresql/postgresql.crt。 如果没有建立SSL连接,则此参数将被忽略。
sslkey #这个参数指定了用于客户端证书的密钥的位置。它可以指定一个文件名,该文件名将被用来替代默认的 ~/.postgresql/postgresql.key,或者它可以指定一个从外部“引擎” (引擎是OpenSSL可加载模块)获取的密钥。外部引擎的指定形式应包含一个由冒号分隔的引擎名称和 一个引擎特定的密钥标识符。如果没有进行SSL连接,则此参数将被忽略。
sslrootcert #这个参数指定一个包含SSL证书颁发机构(CA)证书的文件名。 如果文件存在,服务器的证书将被验证是否由这些机构之一签名。 默认值是~/.postgresql/root.crt。
sslcrl #此参数指定 SSL 证书吊销列表(CRL)的文件名。如果该文件存在,在验证服务器证书时,会拒绝其中列出的证书。默认值为 ~/.postgresql/root.crl。
krbsrvname #使用 Kerberos 5 或 GSSAPI 认证时所用的 Kerberos 服务名。这必须与服务器配置中指定的服务名匹配,Kerberos 认证才能成功。(另请参见第 19.3.5 节和第 19.3.3 节。)
gsslib #用于 GSSAPI 认证的 GSS 库。只在 Windows 上使用。设置为gssapi可强制 libpq 使用 GSSAPI 库而非默认的 SSPI 进行认证。
service #用于额外参数的服务名称。它指定了pg_service.conf中保存额外连接参数的服务名称。 这允许应用程序只指定一个服务名称,以便可以集中维护连接参数。参见第 31.15 节。
如果任何参数未被指定,则会检查对应的环境变量(见第 31.13 节)。如果环境变量也未设置,则使用所指出的内置默认值。
如果 expand_dbname 非零并且dbname包含=符号,就会将其当作一个conninfo字符串处理,方式与将其传给PQconnectdb完全相同(见下文)。之前处理过的关键词会被conninfo字符串中的关键词覆盖。
通常,关键词按索引顺序从这些数组的开头开始处理。其效果是,当关键词重复 出现时,保留最后处理的值。因此,通过仔细放置 dbname 关键词,可以决定哪些值可能被 conninfo 串覆盖, 哪些不能。
PQconnectdb #开启一个到数据库服务器的新连接。
PGconn *PQconnectdb(const char *conninfo);
这个函数使用从字符串conninfo中得到的参数开启一个新的数据库连接。
传入的字符串可以为空以使用全部默认参数,也可以包含一个或多个用空白分隔的参数设置。每一个参数设置的形式都是keyword = value。等号周围的空白是可选的。要写一个空值或一个包含空白的值,将它用单引号包围,例如keyword = 'a value'。值中的单引号和反斜线必须用一个反斜线转义,即\'和\\。
当前能被识别的参数关键词与上面相同。
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完全相同,然后按照上面的方式应用其余参数。
PQsetdb #开启一个到数据库服务器的新连接。
PGconn *PQsetdb(char *pghost,
char *pgport,
char *pgoptions,
char *pgtty,
char *dbName);
这是一个调用PQsetdbLogin的宏,其中为login和pwd参数使用空指针。提供它是为了向后兼容非常老的程序。
PQconnectStartParamsPQconnectStartPQconnectPoll #
PGconn *PQconnectStartParams(const char **keywords,
const char **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 和 host 参数,以确保不会进行名称和反向名称查询。详细信息请参见上文PQconnectdbParams中这些参数的说明。
如果你调用PQtrace,确保接收追踪输出的流对象不会阻塞。
如后文所述,你要确保在调用PQconnectPoll之前,套接字处于合适的状态。
注意:PQconnectStartParams的用法与下文展示的PQconnectStart类似。
要开始无阻塞的连接请求,可调用conn = PQconnectStart("。如果connection_info_string")conn为空,则libpq无法分配一个新的PGconn结构体。否则,一个有效的PGconn指针会被返回(不过还没有表示一个到数据库的有效连接)。从PQconnectStart返回后,调用status = PQstatus(conn)。如果status等于CONNECTION_BAD,则PQconnectStart失败。
如果PQconnectStart成功,下一个阶段是轮询libpq,这样它能够继续进行连接序列。使用PQsocket(conn)来获得该数据库连接底层的套接字描述符。这样循环:如果PQconnectPoll(conn)上一次返回PGRES_POLLING_READING,等到该套接字准备好读取(按照select()、poll()或类似的系统函数所指示的)。则再次调用PQconnectPoll(conn)。反之,如果PQconnectPoll(conn)上一次返回PGRES_POLLING_WRITING,等到该套接字准备好写入,则再次调用PQconnectPoll(conn)。如果你还没有调用过PQconnectPoll,即刚刚调用过PQconnectStart之后,行为就像是它上次返回了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返回一个非空的指针,你必须在用完它之后调用PQfinish来处理该结构体和任何相关的内存块。即使连接尝试失败或被放弃时也必须完成这些工作。
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指针的条目结束。如果无法分配内存,则返回空指针。注意当前默认值(val字段)将依赖于环境变量和其他上下文。调用者必须把连接选项数据当作只读对待。
在处理完选项数组后,把它交给PQconninfoFree释放。如果没有这么做, 每次调用PQconndefaults都会导致一小部分内存泄漏。
PQconninfoParse #返回从提供的连接字符串中解析到的连接选项。
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
解析一个连接字符串并且将结果选项作为一个数组返回,或者在连接字符串有问题时返回NULL。这个函数可以用来抽取所提供的连接字符串中的PQconnectdb选项。返回值指向一个PQconninfoOption结构体的数组,该数组以一个包含空keyword指针的条目结束。
注意,只有在字符串中显式指定的选项才会在结果数组中被设置值;不会插入默认值。
如果errmsg不是NULL,则成功时*errmsg被设为NULL,失败时被设为由malloc分配的、说明问题的错误字符串。(也可能在返回NULL的同时*errmsg被设为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 建立连接完全相同。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。