PostgreSQL 9.4.4 中文手册 | |||
---|---|---|---|
上一页 | 上一级 | 章 31. libpq - C 库 | 下一页 |
下面的函数处理与PostgreSQL服务器联接的事情。
一个应用程序一次可以与多个服务器建立联接。
(这么做的原因之一是访问多于一个数据库。) 每个连接都是用一个从函数
PQconnectdb
、PQconnectdbParams
或PQsetdbLogin
获得的PGconn对象表示。
注意,这些函数总是返回一个非空的对象指针,除非存储器少得连个
PGconn对象都分配不出来。在把查询发送给连接对象之前,
可以调用PQstatus
函数来检查一下返回值看看连接是否成功。
警告 |
在Unix上,用打开的libpq连接分支化一个过程会导致不可预知的结果,
因为父进程和子进程共享同一个套接字和操作系统资源。因为这个原因,
不建议这样的使用,尽管从子进程中执行 |
注意: 在Windows上,如果一个数据库连接重复的启动和关闭,有一个方式提高性能。 内部的,libpq为连接启动和关闭分别调用
WSAStartup()
和WSACleanup()
。WSAStartup()
增加一个内部Windows库引用计数,而WSACleanup()
减少一个。当引用计数是一时,调用WSACleanup()
释放所有资源和所有DLL是空载的。 这是一个昂贵的操作。为了避免它,一个应用可以手动调用WSACleanup()
, 这样在最后一个数据库连接关闭时,资源将不会被释放。
PQconnectdbParams
与数据库服务器建立一个新的连接。
PGconn *PQconnectdbParams(const char * const *keywords, const char * const *values, int expand_dbname);
这个函数用从两个NULL结束的数组中来的参数打开一个新的数据库连接。
第一个,keywords,定义为一个字符串的数组,每个都成为一个关键字。
第二个,values,给每个关键字一个值。与下面的PQsetdbLogin
不同的是,我们可以不必更换函数签名(名字)就可以扩展参数集,
所以我们建议应用程序中使用这个函数(或者它的类似的非阻塞变种
PQconnectStartParams
和PQconnectPoll
)。
目前公认的参数关键字在第 31.1.2 节中列出。
当expand_dbname是非零的时,允许将dbname 的关键字值看做一个连接字符串。只有第一个出现的dbname 是这样展开的,任何随后的dbname值作为纯数据库名处理。 可能的格式的更详细信息在第 31.1.1 节 中显示。
传入的参数可以为空,表明使用所有缺省的参数,或者可以包含一个或更多个参数设置。 它们的长度应该匹配。处理将会在keywords数组的第一个 NULL元素停止。
如果任意参数是NULL或空字符串,则检查对应的环境变量(参阅第 31.14 节)。 如果环境变量也没有设置,则使用指出的内建缺省。
通常,关键字是从这些数组的开始以索引的顺序处理的。这样的影响是,当关键字重复时, 获得最后处理的值。因此,通过小心的放置dbname关键字, 有可能决定哪个被conninfo字符串覆盖,哪个不被覆盖。
PQconnectdb
与数据库服务器建立一个新的连接。
PGconn *PQconnectdb(const char *conninfo);
这个函数用从一个字符串conninfo来的参数与数据库打开一个新的联接。
传入的参数可以为空,表明使用所有缺省的参数,或者可以包含一个或更多个用空白间隔的参数设置, 或者它可以包含一个URI。参阅第 31.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前缀,它被看做一个conninfo字符串,
就和它已经被传递到PQconnectdb
中完全一样,
然后剩余的参数就像为PQconnectdbParams
指定的那样应用。
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和host参数以确保不会发生正向或者反向的名字查找。 参阅第 31.1.2 节里的这些参数的文档获取细节。
如果你调用了PQtrace
,确保你跟踪进入的流对象不会阻塞。
你必须在调用PQconnectPoll
之前确保 socket 处于正确的状态,
像下面描述的那样。
注意: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
将被忽略;判断是否超时是应用的责任。否则,后面跟着一个PQconnectPoll
循环的PQconnectStart
等效于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
结构的数组,该数组以一个有 NULL keyword指针的条目结束。
如果无法分配内存,则返回空指针。注意当前缺省值(val域)
将依赖于环境变量和其他环境。丢失或者无效的服务文件将默默地忽略掉。
调用者必须把连接选项当作只读对待。
在处理完选项数组后,把数组交给PQconninfoFree
释放。
如果没有这么做,每次调用PQconndefaults
都会有一小部分内存泄漏。
PQconninfo
返回活的连接使用的连接选项。
PQconninfoOption *PQconninfo(PGconn *conn);
返回一个连接选项数组。可以用于获取所有可能的PQconnectdb
选项和用于连接到服务器的值。返回值指向一个PQconninfoOption
结构的数组,该数组以一个有 NULL keyword指针的条目结束。
以上所有PQconndefaults
的注意事项也应用到PQconninfo
的结果。
PQconninfoParse
从提供的连接字符串中返回解析的连接选项。
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
解析连接字符串并作为数组返回结果选项;或者如果连接字符串有问题返回NULL。
这个函数可以用来在提供的连接字符串中提取PQconnectdb
选项。
返回值指向一个PQconninfoOption结构的数组,
该数组以一个有 NULL keyword指针的条目结束。
所有合法选项将在结果数组中显示,但是PQconninfoOption 的任何没有在连接字符串中出现的选项将把val设置为NULL; 缺省值不插入。
如果errmsg是非NULL的,那么*errmsg在成功时设置为NULL,
否则是malloc
的解释问题的错误字符串。(*errmsg设置为NULL
并且函数返回NULL是可能的;这表示一个内存溢出条件。)
在处理完选项数组后,把数组交给PQconninfoFree
释放。
如果没有这么做,每次调用PQconndefaults
都会有一小部分内存泄漏。
相反的,如果错误发生了并且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
建立连接的同样的方法使用PQresetPoll
重置连接。
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
的相同。
几个libpq函数分析用户指定的字符串以获取连接参数。 这些字符串有两个可接受的格式:纯keyword = value字符串和 RFC 3986 URIs。
在第一中格式中,每个参数以keyword = value的形式设置。 等号周围的空白是可选的。要写一个空值或者一个包含空白的值,你可以用一对单引号包围它们, 例如,keyword = 'a value'。数值内部的单引号和反斜杠必须用一个反斜杠转义, 比如,\'或\\。
示例:
host=localhost port=5432 dbname=mydb connect_timeout=10
可识别的参数关键字在第 31.1.2 节中列出。
连接URI的通用格式是:
postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
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
URI的层次部分的组件也可以作为参数给出。例如:
postgresql:///mydb?host=localhost&port=5433
百分号可以用在URI的任何部分来包含特殊含义的符号。
忽略任何不对应于在第 31.1.2 节列出的关键字的连接参数, 并将关于它们的警告消息发送到stderr。
为了提高JDBC连接URI的兼容性,参数ssl=true 的实例被翻译成sslmode=require。
主机部分是主机名或者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
目前可识别的参数键字是:
要联接的主机名。如果主机名以斜杠开头, 则它声明使用 Unix 域套接字通讯而不是 TCP/IP 通讯;该值就是套接字文件所存储的目录。 如果没有声明host,那么缺省时是与位于/tmp目录 (或者制作PostgreSQL的时候声明的套接字目录)里面的 Unix-域套接字连接。 在没有 Unix 域套接字的机器上,缺省是与localhost连接。
与之连接的主机的 IP 地址。这个应该是标准的IPv4 地址格式,比如,172.28.40.9。 如果你的机器支持 IPv6,那么你也可以使用 IPv6 的地址。如果声明了一个非空的字符串, 那么使用 TCP/IP 通讯机制。
使用hostaddr取代host可以让应用避免一次主机名查找, 这一点对于那些有时间约束的应用来说可能是非常重要的。不过,GSSAPI 或SSPI认证方法和verify-full SSL证书验证要求主机(host)名。 因此,应用下面的规则:
如果声明了不带hostaddr的host那么就强制进行主机名查找。
如果声明中没有host,hostaddr的值给出服务器网络地址; 如果认证方法要求主机名,那么连接尝试将失败。
如果同时声明了host和hostaddr,那么hostaddr 的值作为服务器网络地址。host的值将被忽略,除非认证方法需要它, 在这种情况下它将被用作主机名。
要注意如果host不是网络地址hostaddr处的服务器名, 那么认证很有可能失败。同样,在~/.pgpass(参阅第 31.15 节) 中是使用host而不是hostaddr来标识连接。
如果主机名(host)和主机地址都没有,那么libpq 将使用一个本地的 Unix 域套接字进行连接;或者是在没有 Unix 域套接字的机器上, 它将尝试与localhost连接。
主机服务器的端口号,或者在 Unix 域套接字联接时的套接字扩展文件名。
数据库名。缺省和用户名相同。在某些情况下,为扩展的格式检查值; 参阅第 31.1.1 节获取更多信息。
要连接的PostgreSQL用户名。 缺省是与运行该应用的用户操作系统名同名的用户。
如果服务器要求口令认证,所用的口令。
连接的最大等待时间,以秒计(用十进制整数字串书写)。零或者不声明表示无穷。 我们不建议把连接超时的值设置得小于 2 秒。
为这个连接设置client_encoding配置参数。 除了对应的服务器选项接受的值,你可以使用auto 从客户端中的当前环境中确定正确的编码(Unix系统上是 LC_CTYPE环境变量)。
添加命令行选项以在运行时发送到服务器。例如,设置为-c geqo=off 设置geqo参数的会话的值为off。关于可用选项的详细讨论, 请查阅第 18 章。
为application_name配置参数指定一个值。
为application_name配置参数指定一个回退值。 如果没有通过连接参数或PGAPPNAME环境变量给定 application_name值,那么将使用这个值。 在想要设置缺省应用名但是允许用户重写的通用实用程序中指定一个回退名是有用的。
控制客户端侧的TCP保持激活是否使用。缺省值是1,意思为打开,但是如果不想要保持激活, 你可以更改为0,意思为关闭。通过Unix域套接字做的连接忽略这个参数。
在TCP应该发送一个保持激活的信息给服务器之后,控制不活动的秒数。 0值表示使用系统缺省。通过Unix域套接字做的连接或者如果禁用了保持激活则忽略这个参数。 只有在TCP_KEEPIDLE和TCP_KEEPALIVE套接字选项可用的系统上支持这个参数, 在Windows上还是在其他系统上是没什么影响的。
在TCP保持激活信息没有被应该传播的服务器承认之后,控制秒数。0值表示使用系统缺省。 通过Unix域套接字做的连接或者如果禁用了保持激活则忽略这个参数。 只有在TCP_KEEPINTVL套接字选项可用的系统上支持这个参数, 在Windows上还是在其他系统上是没什么影响的。
在认为客户端到服务器的连接死亡之前,控制可以丢失的TCP保持激活的数量。0值表示使用系统缺省。 通过Unix域套接字做的连接或者如果禁用了保持激活则忽略这个参数。 只有在TCP_KEEPINTVL套接字选项可用的系统上支持这个参数, 在Windows上还是在其他系统上是没什么影响的。
忽略(以前,这个选项声明服务器日志的输出方向)。
这个选项决定是否需要和服务器协商一个SSL TCP/IP连接, 以及以什么样的安全优先级与服务器进行SSL TCP/IP连接。 这里有六个模式:
只进行一个非SSL连接
首先尝试一个非SSL连接;如果失败,尝试一个SSL连接
首先尝试SSL连接;如果失败,尝试一个非SSL连接
尝试一个SSL连接。如果有根CA文件,则按照指定了verify-ca 的相同方式验证该证书
只尝试一个SSL连接,并核实服务器证书是由一个受信任的认证中心(CA)发布的
只尝试一个SSL连接,核实服务器证书是由受信任的CA发布的, 并且该服务器主机名匹配证书中的服务器主机名。
参阅第 31.18 节获取这些选项工作的详细描述。
Unix域套接字通信忽略sslmode。如果PostgreSQL 编译时没有打开 SSL 支持,那么使用选项require、verify-ca或 verify-full将导致一个错误,而选项allow和prefer 将被接受,但是libpq实际上不会企图进行SSL连接。
这个选项因为有了sslmode设置之后已经废弃了。
如果设为1,则要求与服务器进行SSL联接(等效于sslmode require)。如果服务器不支持SSL,那么libpq 将马上拒绝联接。设置为0(缺省),与服务器进行协商连接类型(等效于sslmode prefer)。这个选项只有在编译PostgreSQL时打开了 SSL 支持才有效。
如果设置为1(缺省),通过SSL连接进行的数据发送将被压缩(这要求OpenSSL 版本0.9.8或更高)。如果设置为0,将禁用压缩(这需要OpenSSL 1.0.0或更高)。 如果连接没有通过SSL进行,或者如果使用的OpenSSL版本不支持它,则忽略该参数。
压缩使用CPU时间,但是如果网络是瓶颈,那么可以提高吞吐量。 如果CPU性能是限制因素,那么禁用压缩可以提高响应时间和吞吐量。
这个参数指定客户端SSL认证的文件名,替换缺省的~/.postgresql/postgresql.crt。 如果没有做SSL连接,则忽略这个参数。
这个参数指定客户端使用的秘钥的位置。也可以指定一个用来替换缺省 ~/.postgresql/postgresql.key的文件名,或者指定一个从外部 "引擎"获取的键(引擎是OpenSSL可加载模块)。 一个外部引擎声明应该包括一个由冒号分隔的引擎名字和特定于引擎的键标识符。 如果没有做SSL连接则忽略这个参数。
这个参数声明一个包含SSL认证授权(CA)证书的文件名。 如果该文件存在,那么将要验证的服务器的证书将由这些授权之一签署。 缺省是~/.postgresql/root.crt。
这个参数声明SSL证书撤销列表(CRL)的文件名。在这个文件中列出的证书, 如果该文件存在,将在尝试认证服务器的证书时被拒绝。缺省是 ~/.postgresql/root.crl。
这个参数声明服务器的操作系统用户名,例如requirepeer=postgres。 当制作一个Unix域套接字连接时,如果设置了该参数,那么在连接的开始, 客户端检查服务器进程是否运行在指定的用户名之下;如果不是,则连接带有错误退出。 这个参数可以用来提供服务器认证,类似于在TCP/IP连接上可用SSL证书。 (请注意,如果Unix域套接字在/tmp中或另一个公开可写位置, 那么任意用户都可以在这里启动一个服务器监听。 使用这个参数确保你连接到一个受信任的用户运行的服务器。) 这个选项只有在实现了peer认证方法的平台上支持;参阅 第 19.3.6 节。
使用GSSAPI认证时使用的Kerberos服务名。 这个名字必须和服务器给Kerberos认证配置的服务名相同,才能认证成功。 (又见第 19.3.3 节。)
为GSSAPI认证使用的GSS库。只在Windows上使用。设置为gssapi 强迫libpq为认证使用GSSAPI库而不是缺省的SSPI。
用于额外参数的服务名。它在pg_service.conf里面声明一个服务名, 这个配置文件保存额外的连接参数。这样就允许应用只声明一个服务名, 而连接参数就可以在一个地方维护了。参阅第 31.16 节。