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 认证方式,以及进行verify-fullSSL 证书验证时,都需要主机名。遵循以下规则:
If host is specified without hostaddr, a host name lookup occurs.
如果指定了hostaddr而没有指定host, 则hostaddr的值给出服务器的网络地址。 如果认证方法需要主机名,则连接尝试将失败。
如果同时指定了 host 和 hostaddr,则 hostaddr 的值给出服务器的网络地址。只有认证方法需要主机名时,才会将 host 的值用作主机名;否则忽略该值。
Note that authentication is likely to fail if host is not the name of the server at network address hostaddr. Also, note that host rather than hostaddr is used to identify the connection in ~/.pgpass (see 第 31.14 节).
如果既没有主机名也没有主机地址,libpq 会使用本地 Unix 域套接字连接;在没有 Unix 域套接字的机器上,则会尝试连接到 localhost。
port #dbname #数据库名称。默认为与用户名相同。
user #建立连接所用的 PostgreSQL 用户名。默认与运行应用程序的操作系统用户名相同。
password #服务器要求密码认证时所使用的密码。
connect_timeout #连接时的最长等待时间,以秒为单位(写成十进制整数字符串)。 零或未指定表示无限等待。不建议使用小于2秒的超时时间。
client_encoding #这将为此连接设置client_encoding配置参数。除了对应服务器选项接受的值外, 您还可以使用auto来从客户端的当前区域设置(Unix系统上的LC_CTYPE环境变量)确定正确的编码。
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连接。有六种模式:
disable仅尝试非SSL连接
allow首先尝试非SSL连接;如果失败,则尝试SSL连接
prefer (default)首先尝试SSL连接;如果失败,则尝试非SSL连接
require仅尝试SSL连接。如果存在根CA文件,则验证证书的方式与指定了verify-ca时相同
verify-ca仅尝试SSL连接,并验证服务器证书是否由受信任的证书颁发机构(CA)颁发
verify-full仅尝试SSL连接,验证服务器证书是否由受信任的CA颁发,并且请求的服务器主机名与证书中的匹配
See 第 31.17 节 for a detailed description of how these options work.
在 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。
requirepeer #这个参数指定了服务器的操作系统用户名,例如requirepeer=postgres。 在建立Unix域套接字连接时,如果设置了这个参数,客户端会在连接开始时检查服务器进程是否在指定的用户下运行; 如果不是,则连接会因错误而中止。 这个参数可用于提供类似于在TCP/IP连接上使用SSL证书的服务器认证。 (请注意,如果Unix域套接字位于/tmp或其他公共可写位置, 任何用户都可以在那里启动一个服务器监听。使用这个参数来确保您连接到由受信任用户运行的服务器。) 此选项仅在实现了peer认证方法的平台上受支持;请参见第 19.3.7 节。
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 节。
If any parameter is unspecified, then the corresponding environment variable (see 第 31.13 节) is checked. If the environment variable is not set either, then the indicated built-in defaults are used.
如果 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相同。
Neither PQconnectStartParams nor PQconnectStart nor PQconnectPoll will block, so long as a number of restrictions are met:
必须恰当地使用 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,该函数已在上文介绍。在异步连接过程中(也仅在此过程中)还可能出现其他状态。它们指明连接过程的当前阶段,例如可以用来向用户提供反馈。这些状态如下:
Note that, although these constants will remain (in order to maintain compatibility), an application should never rely upon these occurring in a particular order, or at all, or on the status always being one of these documented values. An application might do something like this:
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 分配的、用于说明问题的错误字符串。 (也可能出现 *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 **keywords, const char **values, int expand_dbname);
该函数返回以下值之一:
PQping #PQping报告服务器状态。它接受的连接参数与上文介绍的PQconnectdb相同。但取得服务器状态并不需要提供正确的用户名、密码或数据库名值。
PGPing PQping(const char *conninfo);
返回值与 PQpingParams 相同。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。