# 48.2\. 消息流
本节描述消息流,以及每种消息类型的语意(每种消息的准确表现细节在[Section 48.5](#calibre_link-1026)里)。 因连接的状态不同,存在几种不同的子协议:启动、查询、函数调用、`COPY` 、结束。 还有用于异步操作(包括通知响应和命令取消)的特殊规定,这些异步操作可能在启动阶段过后的任何时间产生。
## 48.2.1\. 启动
要开始一个会话,前端打开一个与服务器的连接并且发送一个启动消息。 这个消息包括用户名以及用户希望与之连接的数据库;它还标识要使用的特定的协议版本。 (另外,启动消息可以包括用于运行时参数的额外设置。) 服务器然后就使用这些信息以及它的配置文件的内容(比如 `pg_hba.conf`)以判断这个连接是否可以接受,以及需要什么样的额外的认证(如果有)。
然后服务器就发送合适的认证请求消息,前端必须用合适的认证响应消息来响应(比如一个口令)。 对所有的认证方法,除了GSSAPI和SSPI,最多只有一次请求和响应。 有些认证方法则根本不需要前端的响应,因此就没有认证请求发生。 对于GSSAPI和SSPI,为了完成认证则可能需要多次数据包的交换。
认证周期的结束要么是服务器拒绝连接(ErrorResponse),要么是服务器发送AuthenticationOk消息。
这个阶段来自服务器可能消息是:
ErrorResponse
连接请求被拒绝。然后服务器马上关闭连接。
AuthenticationOk
认证信息的交换成功完成。
AuthenticationKerberosV5
现在前端必须与服务器进行一次 KerberosV5 认证对话(是Kerberos规范的一部分,在这里没有描述)。 如果对话成功,服务器响应一个 AuthenticationOk消息,否则它响应一个 ErrorResponse消息。
AuthenticationCleartextPassword
现在前端必须发送一个包含明文口令的 PasswordMessage包。 如果这是正确的口令,服务器用一个 AuthenticationOk 包响应,否则它响应一个 ErrorResponse 包。
AuthenticationMD5Password
现在前端必须发送一个包含用 MD5 加密的口令(包括用户名)的 PasswordMessage ,加密时使用在 AuthenticationMD5Password 消息里指定的 4 字节随机盐粒。 如果这是正确口令,服务器用一个 AuthenticationOk 响应,否则它用一个 ErrorResponse 响应。 实际的PasswordMessage可以通过SQL语句`concat('md5',md5(concat(md5(concat(password, username)), random-salt)))`计算得到。 (注意`md5()` 函数的返回值是16进制表示的字符串。)
AuthenticationSCMCredential
这个响应只会在那些支持 SCM 信任消息的本地 Unix 域连接上出现。 前端必须发出一条 SCM 信任消息然后发送一个数据字节。 (数据字节的内容并不会被关心;它的作用只是确保服务器等待了足够长的时间来接受信任信息。) 如果信任是可以接受的,那么服务器用 AuthenticationOk 响应,否则用 ErrorResponse 响应。 (只有9.1以前的服务器才可能发出这个消息,并且这个消息最终可能会被从协议中删除。)
AuthenticationGSS
现在前端必须发起一个GSSAPI协商。 作为响应前端将随着GSSAPI数据流的最初部分发送一个PasswordMessage包。 如果需要进一步的消息,服务端将以AuthenticationGSSContinue作为响应。
AuthenticationSSPI
现在前端必须发起一个SSPI协商。 作为响应前端将随着SSPI数据流的最初部分发送一个PasswordMessage包。 如果需要进一步的消息,服务端将以AuthenticationGSSContinue作为响应。
AuthenticationGSSContinue
这个消息包含GSSAPI或SSPI协商的上一个步骤(AuthenticationGSS, AuthenticationSSPI或前一个AuthenticationGSSContinue)的响应数据。 如果这个消息中的GSSAPI或SSPI数据指示需要更多的数据以完成认证过程,前端必须用另一个PasswordMessage包发送这些数据。 如果通过这个消息GSSAPI或SSPI认证已完成,服务端下次将发送AuthenticationOk指示认证成功或ErrorResponse指示认证失败。
如果前端不支持服务器要求的认证方式,那么它应该马上关闭连接。
在收到 AuthenticationOk 包之后,前端必须等待来自后端的更多消息。 在这个阶段会启动一个后端进程,而前端只是一个感兴趣的看热闹的。 启动尝试仍然有可能失败 (ErrorResponse),但是通常情况下,后端将发送一些 ParameterStatus 消息、BackendKeyData 、最后是 ReadyForQuery 。
在这个阶段,后端将尝试应用任何在启动消息里给出的额外的运行时参数设置。 如果成功,这些值将成为会话的缺省值。错误将导致 ErrorResponse 并退出。
这个阶段来自后端的可能消息是:
BackendKeyData
这个消息提供了密钥(secret-key)数据,前端如果想要在稍后发出取消的请求,则必须保存这个数据。 前端不应该响应这个消息,但是应该继续侦听等待 ReadyForQuery 消息。
ParameterStatus
这个消息告诉前端有关后端参数的当前(初始化)设置,比如 [client_encoding](#calibre_link-1030) 或 [DateStyle](#calibre_link-787) 等。 前端可以忽略这个消息,或者记录其设置用于将来使用;参阅[Section 48.2.6](#calibre_link-1020)获取更多细节。 前端不应该响应这个消息,而是应该继续侦听 ReadyForQuery 消息。
ReadyForQuery
后端启动成功,前端现在可以发出命令。
ErrorResponse
后端启动失败。在发送完这个消息之后连接被关闭。
NoticeResponse
发出了一个警告消息。前端应该显示这个消息,并且继续等待 ReadyForQuery 或 ErrorResponse 。
后端在每个查询循环后都会发出一个相同的 ReadyForQuery 消息。 前端可以合理地认为 ReadyForQuery 是一个查询循环的开始, 或者认为 ReadyForQuery 是启动阶段和每个随后查询循环的结束,具体是哪种情况取决于前端的编码需要。
## 48.2.2\. 简单查询
一个查询循环是由前端发送一条 Query 消息给后端进行初始化的。 这条消息包含一个用文本字符串表示的 SQL 命令(或者一些命令)。 后端根据查询命令字符串的内容发送一条或者更多条响应消息给前端,并且最后是一条 ReadyForQuery 响应消息。 ReadyForQuery 通知前端它可以安全地发送新命令了。 (实际上前端不必在发送其它命令之前等待 ReadyForQuery ,但是这样一来,前端必须负责区分早先发出的命令失败,而稍后发出的命令成功的情况。)
从后端来的可能的消息是:
CommandComplete
一个 SQL 命令正常结束
CopyInResponse
后端已经准备好从前端拷贝数据到一个表里面去。又见[Section 48.2.5](#calibre_link-1019)。
CopyOutResponse
后端已经准备好从一个表里拷贝数据到前端里面去。又见[Section 48.2.5](#calibre_link-1019)。
RowDescription
表示为了响应一个 `SELECT`, `FETCH` 等的查询,将要返回一个行。 这条消息的内容描述了这行的字段布局。这条消息后面将跟着每个返回给前端的行一个的 DataRow 消息。
DataRow
`SELECT`, `FETCH` 等查询返回的结果集中的一行。
EmptyQueryResponse
识别了一个空的查询字符串。
ErrorResponse
出错了。
ReadyForQuery
查询字符串的处理完成。发送一个独立的消息来标识这个是因为查询字符串可能包含多个 SQL 命令。 (CommandComplete 只是标记一条 SQL 命令处理完毕,而不是整个字符串。) ReadyForQuery 总会被发送,不管是处理成功结束还是产生错误。
NoticeResponse
发送了一个与查询有关的警告消息。注意警告消息是附加在其它响应上的,也就是说,后端将继续处理该命令。
`SELECT`(或其它返回结果集的查询,比如 `EXPLAIN` 或 `SHOW`)查询的响应通常包含 RowDescription ,零个或者多个 DataRow 消息,以及最后的 CommandComplete 。 从或者到前端的 `COPY` 使用[Section 48.2.5](#calibre_link-1019)里提到的特殊的协议。所有其它查询类型通常只生成一个 CommandComplete 消息。
因为查询字符串可能包含若干个查询(用分号分隔),所以在后端完成查询字符串的处理之前可能有好几个这样的响应序列。 如果整个字符串已经处理完,后端已经准备好接受新查询字符串的时候则发出 ReadyForQuery 消息。
如果收到一个完全空(除了空白之外没有内容)的查询字符串,那么响应是一条 EmptyQueryResponse 后面跟着 ReadyForQuery 。
在出现错误的时候,发出一个 ErrorResponse 消息,后面跟着 ReadyForQuery 。 查询字符串的所有后继的处理都被 ErrorResponse 中止(即使里面还有查询也这么干)。 请注意这些事情可能在处理一个查询产生的消息序列的中途发生。
在简单查询模式,检索出来的数值的格式总是文本的,除非给出的命令是从一个声明了`BINARY`选项的游标上的`FETCH` 。 在这种情况下,检索出来的数值是二进制格式的。在 RowDescription 消息里给出的格式代码告诉用了哪种格式。
前端在等待其它类型的消息时必须准备接收 ErrorResponse 和 NoticeResponse 消息。 参阅[Section 48.2.6](#calibre_link-1020)后端因为外部的事件可能生成的消息。
建议的方法是把前端代码写成状态机的风格,它可以在任何时刻接受任何有意义的消息,而不是写成假设消息的准确序列的代码。
## 48.2.3\. 扩展查询
扩展的查询协议把上面描述的简单协议分裂成若干个步骤。准备的步骤可以多次复用以提高效率。 另外,还可以获得额外的特性,比如把数据值作为独立的参数提供的可能性,而不是把它们直接插入一个查询字符串。
在扩展的协议里,前端首先发送一个 Parse 消息,它包含一个文本查询字符串,另外还有一些有关参数占位符的数据类型的信息,以及一个最终预备语句对象的名字(一个空字符串选择未命名的预备语句)。 响应要么是一个 ParseComplete 要么是 ErrorResponse 。参数数据类型可以用 OID 来声明;如果没有给出,那么分析器将试图用它对付无类型的字符串常量的方法来推导其数据类型。
> **Note:** 一个参数数据类型可以通过设置为零,或者让参数类型 OID 的数目比查询字符串里的参数符号(`$``_n_`)的数目少的方法不予声明。 另外一个特例是参数的类型可以声明为 `void`(也就是伪类型 `void` 的 OID)。 这是为了允许用于某些函数参数的参数符号实际上是 OUT 参数。 通常情况下,没有什么环境会用到 `void` 参数,但是如果在函数的参数列表里出现了这么一个参数符号,那么它实际上会被忽略。 比如,一个像这样的函数调用:`foo($1,$2,$3,$4)`,如果`$3`和`$4`声明为类型是 `void` ,那么这个函数调用可以匹配一个带有两个 IN 和两个 OUT 参数的函数。
> **Note:** 在一个 Parse 消息里包含的查询字符串不能包含超过一个 SQL 语句;否则就会报告一个语法错误。 这个限制在简单查询协议中并不存在,但是它存在于扩展的协议中,因为允许预备语句或者入口包含多个命令将导致协议过度地复杂。
如果成功创建了一个命名的预备语句对象,那么它将持续到当前会话结束,除非明确删除。 一个未命名的预备语句只持续到下一个声明未命名的语句的 Parse 语句发出为止(请注意一个简单的查询消息也删除未命名语句)。 命名的预备语句必须明确地关闭,然后才能用一个 Parse 消息重新定义,但是未命名的语句并不要求这个动作。 命名的预备语句也可以在 SQL 命令级创建和访问,方法是使用 `PREPARE` 和 `EXECUTE`。
只要预备语句还存在,那么就可以使用 Bind 消息很容易地使之进入执行状态。 Bind 消息给出源预备语句的名字(空字符串表示未命名的预备语句),目标入口的名字(空字符串表示未命名的入口),以及用于那些在预备语句中出现的所有参数占位符的数值。 提供的参数集必须匹配那些预备语句需要的东西。(如果你在 Parse 消息里声明任何 `void` 参数,那么在 Bind 消息里给它们传递 NULL 值。) Bind 还声明用于查询返回的任何数据的格式;格式可以一次声明,也可以每个字段进行声明。响应要么是 BindComplete 要么是 ErrorResponse 。
> **Note:** 输出的格式是文本还是二进制是由 Bind 里给出的格式代码决定的,不管用的是什么 SQL 命令。 在使用扩展的查询协议的时候,游标声明里的 `BINARY` 属性是不起作用的。
典型的查询计划在处理Bind消息后生成。 预备语句如果不包含参数,或者被反复执行的情况下,服务端可能会保存创建好的查询计划并在后续的针对同样的Bind消息中重用它。 但是,只有确保这样作成的通用的查询计划不至于比依赖于特定参数值的查询计划效率差太多的情况下,服务端才会这么做。 就协议而言这些是透明的。
如果成功创建了一个命名的入口对象,那么它将持续到当前会话结束,除非明确删除。 一个未命名的入口只持续到事务结束或下一个声明未命名的入口的 Bind消息发出为止(请注意一个简单的查询消息也删除未命名入口)。 命名的入口必须明确地关闭,然后才能用另一个 Bind 消息重新定义,但是未命名的语句并不要求这个动作。 命名的入口也可以在 SQL 命令级创建和访问,方法是使用`DECLARE CURSOR`和`FETCH`。
只要存在一个入口,那么就可以用一个 Execute 消息执行它。 Execute 消息声明入口的名字(空字符串表示未命名入口)和一个最大的结果行计数(零表示"抓取所有行")。 结果行计数只对包含返回结果集的入口有意义;在其它情况下,该命令总是执行到结束,而行计数会被忽略。 Execute 可能的响应和那些通过简单查询协议发出的查询一样,只不过 Execute 不会导致后端发出 ReadyForQuery 或者 RowDescription 。
如果 Execute 在一个入口的执行完成之前终止(因为达到了一个非零的结果行计数),它将发送一个 PortalSuspended 消息;这个消息的出现告诉前端应该在同一个入口上发出另外一个 Execute 以完成操作。 在入口的执行完成之前,不会发出表示源 SQL 命令结束的 CommandComplete 消息。 因此 Execute 阶段的结束总是由出现下列之一的消息标志的:CommandComplete 、EmptyQueryResponse(如果入口是从一个空字符串创建出来的)、ErrorResponse 、PortalSuspended 。
每个扩展查询消息序列完成后,前端都应该发出一条 Sync 消息。 这个无参数的消息导致后端关闭当前事务——如果当前事务不是在一个`BEGIN`/`COMMIT`事务块中的话("关闭"的意思就是在没有错误的情况下提交,或者是有错误的情况下回滚)。 然后响应一条 ReadyForQuery 消息。Sync 的目的是提供一个错误恢复的重新同步的点。 如果在处理任何扩展查询消息的时候侦测到任何错误,那么后端发出 ErrorResponse ,然后读取并抛弃消息,直到一个 sync 的到来,然后发出 ReadyForQuery 并且返回到正常的消息处理中。 (但是要注意如果_正在_处理 Sync 的时候发生了错误,那么不会忽略任何东西 —这样就保证了为每个 Sync 发出一个并且只有一个的 ReadyForQuery 。
> **Note:** Sync 并不导致一个用`BEGIN`打开的事务块关闭。可以侦测到这种情况,因为 ReadyForQuery 消息包含事务状态信息。
除了这些基本的,必须的操作之外,在扩展查询协议里还有几种可选的操作可以使用。
Describe 消息(入口变体)指定一个现有的入口的名字(如果是一个未命名的入口则是一个空字符串)。 响应是一个 RowDescription 消息,它描述了执行入口将要返回的行;或者是一个 NoData 消息(如果入口并不包含会返回行的查询);或者是一个 ErrorResponse(如果没有这个入口)。
Describe 消息(语句变体)指定一个现有的预备语句的名字(如果是一个未命名的预备语句则是一个空字符串)。 响应是一个描述该语句需要的参数的 ParameterDescription 消息,后面跟着一个描述语句最终执行后返回的行的 RowDescription 消息(或者是 NoData 消息,如果该语句不返回行)。 如果没有这样的预备语句,则返回 ErrorResponse 。 请注意因为还没有发出 Bind ,所以后端还不知道用于返回字段的格式;在这种情况下,RowDescription 消息里面的格式代码字段将是零。
> **Tip:** 在大多数情况下,前端在发出 Execute 之前应该发出某种 Describe 的变体,以保证它知道如何解析它将得到的结果。
Close 消息关闭一个现有的预备语句或者入口,并且释放资源。 对一个不存在的语句或者入口名字发出 Close 不是一个错误。 响应通常是 CloseComplete ,但如果在释放资源的时候发生了一些困难也可以是 ErrorResponse 。 请注意关闭一个预备语句隐含地关闭任何从该语句构造出来的打开的入口。
Flush 消息并不导致任何特定的输出的生成,但是强制后端发送任何还在它的输出缓冲区中停留的数据。 Flush 必须在除 Sync 外的任何扩展查询命令后面发出(如果前端希望在发出更多的命令之前检查该命令的结果的话)。 如果不 Flush ,后端返回的消息将组合成最小可能的数据包个数,以减少网络负荷。
> **Note:** 简单查询消息大概等于一系列使用未命名的预备语句和无参数的入口对象的 Parse 、Bind 、入口 Describe 、Execute 、Close 、Sync 。 一个区别是它会在查询字符串中接受多个 SQL 语句,并在会话中为每个语句自动执行绑定/描述/执行序列。 另外一个区别是它不会返回 ParseComplete 、Bindcomplete 、CloseComplete 、NoData 消息。
## 48.2.4\. 函数调用
函数调用子协议允许客户端请求一个对存在于数据库`pg_proc`系统表中的任意函数的直接调用。 客户端必须在该函数上有执行的权限。
> **Note:** 函数调用子协议是一个遗留的特性,在新代码里最好避免用它。 类似的结果可以通过设置一个`SELECT function($1, ...)`预备语句获得。 这样函数调用循环就可以用 Bind/Execute 代替。
一个函数调用循环是由前端向后端发送一条 FunctionCall 消息初始化的。 然后后端根据函数调用的结果发送一条或者更多响应消息,并且在最后是一条 ReadyForQuery 响应消息。 ReadyForQuery 通知前端它可以安全地发送一条新的查询或者函数调用了。
从后端来的可能的消息是:
ErrorResponse
发生了一个错误。
FunctionCallResponse
函数调用完成并且在消息中返回一个结果。 (请注意,函数调用协议只能处理单个标量结果,不能处理行类型或者结果集。)
ReadyForQuery
函数调用处理完成。ReadyForQuery 将总是被发送,不管是成功完成处理还是发生了一个错误。
NoticeResponse
发出了一条有关该函数调用的警告消息。通知是附加在其它响应上的,也就是说,后端将继续处理命令。
## 48.2.5\. COPY操作
`COPY`命令允许在服务器和客户端之间高速的大批量数据传输。 拷贝入和拷贝出操作每个都把连接切换到一个独立的子协议中,并且持续到操作结束。
拷贝入模式(数据传输到服务器)是在后端执行一个`COPY FROM STDIN`语句的时候初始化的。 后端发送一个 CopyInResponse 消息给前端。 前端应该发送零条或者更多 CopyData 消息,形成一个输出数据的流。 (消息的边界和行的边界没有任何相关性要求,尽管通常那就是合理的边界选择。) 前端可以通过发送一个 CopyDone 消息来终止拷贝入操作(允许成功终止),也可以发出一个 CopyFail 消息(它将导致 `COPY` 语句带着错误失败)。 然后后端就恢复回它在 `COPY` 开始之前的命令处理模式,可能是简单查询协议,也可能是扩展查询协议。 然后它会发送 CommandComplete(如果成功)或者 ErrorResponse(如果失败)。
如果在拷贝入模式下后端检测到了错误(包括接受接收到 CopyFiail 消息,或者是任何除了 CopyData 或者 CopyDone 之外的前端消息),那么后端将发出一个 ErrorResponse 消息。 如果`COPY` 命令是通过一个扩展的查询消息发出的,那么后端从现在开始将抛弃前端消息,直到一个 Sync 消息到达,然后它将发出 ReadyForQuery 并且返回到正常的处理中。 如果`COPY` 命令是在一个简单查询消息里发出的,那么该消息剩余部分被丢弃然后发出 ReadyForQuery 消息。 不管是哪种情况,任何前端发出的 CopyData, CopyDone, CopyFail 消息都将被简单地抛弃。
后端将会忽略拷贝入模式时接收到的 Flush 和 Sync 消息。 收到任何其它非拷贝消息,会引发错误,如前所述这样会导致退出拷贝入状态。 (Flush 和 Sync 的例外是为了方便客户端库在执行 Execute 消息后始终发送 Flush 或 Sync 而不检查所执行的命令是否是一个 COPY FROM STDIN 命令。)
拷贝出模式(数据从服务器发出)是在后端执行一个`COPY TO STDOUT`语句的时候初始化的。 后端发出一个 CopyOutResponse 消息给前端,后面跟着零或者多个 CopyData 消息(总是每行一个),然后跟着 CopyDone 。 然后后端回退到它在`COPY`开始之前的命令处理模式,然后发送 CommandComplete 。 前端不能退出传输(除非是关闭连接或者发出一个 Cancel 请求),但是它可以抛弃不需要的 CopyData 和 CopyDone 消息。
在拷贝出模式中,如果后端检测到错误,那么它将发出一个 ErrorResponse 消息并且回到正常的处理。 前端应该把收到 ErrorResponse当作终止拷贝出模式的标志。
NoticeResponse和ParameterStatus消息有可能夹在CopyData消息间出现。 前端必须处理这种情况,并且也应该准备好处理其它异步消息(参阅[Section 48.2.6](#calibre_link-1020))。 除此以外,任何CopyData和CopyDone以外的消息应该被视作拷贝出模式的中止。
还有一个拷贝相关的模式,称作双向拷贝,它允许从_和_到服务端的高速的批量数据传输。 双向拷贝模式由处于walsender模式的后端执行一条`START_REPLICATION`语句初始化。 后端发送一个CopyBothResponse给前端。然后后端和前端可能都发送CopyData消息,直到有一方发出一个CopyDone消息。 客户端发送CopyDone消息后,连接从双向拷贝模式切换到拷贝出模式,并且客户端不应该再发出任何CopyData消息。 相似的,如果服务端发出CopyDone消息,连接进入拷贝入模式,并且服务端不应该再发出任何CopyData消息。 两边都发送了CopyDone消息后,拷贝模式终止,后端返回到命令处理模式。 在双向拷贝模式中,如果后端检出错误,将发出一个ErrorResponse消息,丢弃任何来自前端的消息直到收到Sync消息,然后发送ReadyForQuery消息并返回到普通的处理模式。 前端应把收到ErrorResponse消息作为在两个方向上都终止拷贝的标志,这个时候不应该发出CopyDone消息。 请参阅[Section 48.3](#calibre_link-1024)获得更多有关双向拷贝模式下子协议传输的信息。
CopyInResponse,CopyOutResponse和 CopyBothResponse 消息包含了告诉前端每行的字段数以及每个字段使用的格式代码的信息。 (就目前的实现而言,某个`COPY`操作的所有字段都使用同样的格式,但是消息设计并不做这个假设。)
## 48.2.6\. 异步操作
有几种情况下后端会发送一些并非由特定的前端的命令流提示的消息。 在任何时候前端都必须准备处理这些消息,即使是并未涉及到查询处理的时候。 至少,应该在开始读取查询响应之前检查这些情况。
NoticeResponse 消息有可能是因为外部的活动而生成的;比如,如果数据库管理员进行一次"快速"数据库关闭,那么后端将在关闭连接之前发送一个 NoticeResponse 来通知这件事。 因此,前端应该总是准备接受和显示 NoticeResponse 消息,即使连接表面上是空闲的时候也如此。
如果后端认为前端应该知道的任何参数的实际值发生了变化,那么都会产生 ParameterStatus 消息。 这些最经常发生的地方是前端执行的一个`SET`命令的响应,并且这个时候实际上是同步(但是也有可能是数据库管理员改变了配置文件然后SIGHUP了服务器导致的参数状态的变化)。 同样,如果一个`SET`命令回滚,那么也会生成合适的 ParameterStatus 消息以报告当前有效的数值。
目前,系统内有一套会生成 ParameterStatus 消息的硬编码的参数:他们是 `server_version`、`server_encoding`、`client_encoding`、`application_name`、`is_superuser`、`session_authorization`、`DateStyle`、`IntervalStyle`、`TimeZone`、`integer_datetimes`以及`standard_conforming_strings`。 (8.0以前的版本不会报告`server_encoding`、`TimeZone`和`integer_datetimes`。 8.1以前的版本不会报告`standard_conforming_strings`。 8.4以前的版本不会报告`IntervalStyle`。 9.0以前的版本不会报告`application_name`。) 请注意`server_version`、`server_encoding`和`integer_datetimes`是伪参数,启动后不能修改。 这个参数集合可能在将会改变,或者甚至是变成可以配置的。因此,前端应该简单地忽略那些它不懂或者不关心的 ParameterStatus 。
如果前端发出一个`LISTEN`命令,那么为同一个通道名执行了`NOTIFY`命令后,将收到后端发来的一个 NotificationResponse 消息(不要和 NoticeResponse 混淆)。
> **Note:** 目前,NotificationResponse 只能在一个事务外面发送,因此它将不会在一个命令响应序列中间出现,但是它可能在 ReadyForQuery 之前出现。 不过,在前端逻辑中做上述假设是不明智的。好的做法是在协议的任何点上都可以接受 NotificationResponse 。
## 48.2.7\. 取消正在处理的请求
在一条查询正在处理的时候,前端可能请求取消这个查询。 这样的取消请求不是直接通过打开的当前连接发送给后端的,这么做是因为实现的有效性:不希望后端在处理查询的过程中不停地检查前端来的输入。 取消请求应该相对而言比较少见,所以把取消做得稍微笨拙一些,以便不影响正常状况的性能。
要发送一条取消请求,前端打开一个与服务器的新连接并且发送一条 CancelRequest 消息,而不是通常在新连接中经常发送的 StartupPacket 消息。 服务器将处理这个请求然后关闭连接。出于安全原因,对取消请求消息不做直接的响应。
除非 CancelRequest 消息包含与连接启动过程中传递给前端的相同的键数据(PID 和安全键字),否则它将被忽略。 如果该请求匹配当前运行着的后端的 PID 和安全键字,则退出当前查询的处理(目前的实现里采用的方法是向正在处理该查询的后端进程发送一个特殊的信号)。
取消信号可能有也可能没有任何作用。 例如,如果它在后端已经完成了查询的处理后到达,那么它就没有作用。 如果取消起作用了,其结果是当前命令带着一个错误消息提前退出。
这么做是对安全和有效性通盘考虑的结果,前端没有直接的方法获知一个取消请求是否成功。 它必须继续等待后端对查询响应。执行取消仅仅是增加了当前查询快些结束的可能性,以及增加了当前查询会带着一条错误消息失败而不是成功执行的可能性。
因为取消请求是通过新的连接发送给服务器而不是通过通常的前/后端通讯连接,所以取消请求可能是任意进程执行的,而不仅仅是要取消查询的前端。 这样可能对创建多进程应用有某种灵活性的好处。但是同时这样也带来了安全风险,因为这样任何一个非认证用户都可能试图取消查询。 这个安全风险通过要求在取消请求中提供一个动态生成的安全键字排除。
## 48.2.8\. 终止
通常,优雅的终止过程是前端发送一条 Terminate消息并且立刻关闭连接。一旦收到这个消息,后端马上关闭连接并且退出。
在少数情况下(比如通过一个管理员命令关闭数据库),后端可能在没有任何前端请求的情况下断开连接。 在这种情况下,后端将在它断开连接之前尝试发送一个错误或者通知消息,给出断开的原因。
其它终止的情况发生在各种失效的场合,比如某一方的内核转储,失去通讯链路,丢失了消息边界同步等。 不管是前端还是后端看到了一个意外的连接关闭,那么它应该清理现场并且终止。 如果前端不想终止自己,那么它可以通过再次连接服务器的方式重启一个新的后端。 如果收到了一个无法识别的消息,那么也建议关闭连接,因为出现这种情况可能意味着是丢失了消息边界的同步。
不管是正常还是异常的终止,任何打开的事务都会回滚,而不是提交。 不过,应该注意的是如果一个前端在一个非`SELECT`查询正在处理的时候断开,那么后端很可能在注意到断开之前先完成查询的处理。 如果查询处于任何事务块之外((`BEGIN` ... `COMMIT`序列),那么其结果很可能在得知断开之前被提交。
## 48.2.9\. SSL会话加密
如果编译PostgreSQL的时候打开了SSL支持,那么前后端通讯就可以用SSL加密。 这样就提供了一种在攻击者可能捕获会话通讯数据包的环境下保证通讯安全的方法。 有关使用SSL加密PostgreSQL会话的更多信息,请参阅[Section 17.9](#calibre_link-657)。
要开始一次SSL加密连接,前端先是发送一个 SSLRequest 消息,而不是 StartupMessage 。 然后服务器以一个包含`S`或`N`的字节响应,分别表示它愿意还是不愿意进行SSL。 如果前端对响应不满意,那么它可以关闭连接。 要在`S`之后继续,那么先进行与服务器的SSL启动握手(没有在这里描述,这是SSL规范的一部分)。 如果这些成功了,那么继续发送普通的 StartupMessage 。 这种情况下,StartupMessage 和所有随后的数据都将由SSL加密。 要在`N`之后继续,则发送普通的 StartupMessage 然后不带加密进行处理。
前端应该也准备处理一个来自服务器的给 SSLRequest 的 ErrorMessage 响应。 这种情况只有在那些SSL支持被加入到PostgreSQL以前的服务上才会出现。 (这样的服务器太古老了,很可能根本就不存在。) 在这种情况下,连接必需关闭,但是前端可以选择打开一个新的连接然后不带SSL进行连接。
一个初始化的 SSLRequest 也可以用于为了发送一条 CancelRequest 消息而打开的连接中。
如果协议本身并未提供某种方法强制SSL加密,那么管理员可以把服务器配置为拒绝未加密的会话,这是认证检查的一个副产品。
- 前言
- 何为PostgreSQL?
- PostgreSQL简史
- 格式约定
- 更多信息
- 臭虫汇报指导
- I. 教程
- Chapter 1. 从头开始
- 1.1. 安装
- 1.2. 体系基本概念
- 1.3. 创建一个数据库
- 1.4. 访问数据库
- Chapter 2. SQL语言
- 2.1. 介绍
- 2.2. 概念
- 2.3. 创建新表
- 2.4. 向表中添加行
- 2.5. 查询一个表
- 2.6. 在表间连接
- 2.7. 聚集函数
- 2.8. 更新
- 2.9. 删除
- Chapter 3. 高级特性
- 3.1. 介绍
- 3.2. 视图
- 3.3. 外键
- 3.4. 事务
- 3.5. 窗口函数
- 3.6. 继承
- 3.7. 结论
- II. SQL 语言
- Chapter 4. SQL语法
- 4.1. 词法结构
- 4.2. 值表达式
- 4.3. 调用函数
- Chapter 5. 数据定义
- 5.1. 表的基本概念
- 5.2. 缺省值
- 5.3. 约束
- 5.4. 系统字段
- 5.5. 修改表
- 5.6. 权限
- 5.7. 模式
- 5.8. 继承
- 5.9. 分区
- 5.10. 外部数据
- 5.11. 其它数据库对象
- 5.12. 依赖性跟踪
- Chapter 6. 数据操作
- 6.1. 插入数据
- 6.2. 更新数据
- 6.3. 删除数据
- Chapter 7. 查询
- 7.1. 概述
- 7.2. 表表达式
- 7.3. 选择列表
- 7.4. 组合查询
- 7.5. 行排序
- 7.6. LIMIT和OFFSET
- 7.7. VALUES列表
- 7.8. WITH 查询 (通用表表达式)
- Chapter 8. 数据类型
- 8.1. 数值类型
- 8.2. 货币类型
- 8.3. 字符类型
- 8.4. 二进制数据类型
- 8.5. 日期/时间类型
- 8.6. 布尔类型
- 8.7. 枚举类型
- 8.8. 几何类型
- 8.9. 网络地址类型
- 8.10. 位串类型
- 8.11. 文本搜索类型
- 8.12. UUID 类型
- 8.13. XML 类型
- 8.14. JSON 类型
- 8.15. Arrays
- 8.16. 复合类型
- 8.17. 范围类型
- 8.18. 对象标识符类型
- 8.19. 伪类型
- Chapter 9. 函数和操作符
- 9.1. 逻辑操作符
- 9.2. 比较操作符
- 9.3. 数学函数和操作符
- 9.4. 字符串函数和操作符
- 9.5. 二进制字符串函数和操作符
- 9.6. 位串函数和操作符
- 9.7. 模式匹配
- 9.8. 数据类型格式化函数
- 9.9. 时间/日期函数和操作符
- 9.10. 支持枚举函数
- 9.11. 几何函数和操作符
- 9.12. 网络地址函数和操作符
- 9.13. 文本检索函数和操作符
- 9.14. XML 函数
- 9.15. JSON 函数和操作符
- 9.16. 序列操作函数
- 9.17. 条件表达式
- 9.18. 数组函数和操作符
- 9.19. 范围函数和操作符
- 9.20. 聚集函数
- 9.21. 窗口函数
- 9.22. 子查询表达式
- 9.23. 行和数组比较
- 9.24. 返回集合的函数
- 9.25. 系统信息函数
- 9.26. 系统管理函数
- 9.27. 触发器函数
- 9.28. 事件触发函数
- Chapter 10. 类型转换
- 10.1. 概述
- 10.2. 操作符
- 10.3. 函数
- 10.4. 值存储
- 10.5. UNION, CASE 和相关构造
- Chapter 11. 索引
- 11.1. 介绍
- 11.2. 索引类型
- 11.3. 多字段索引
- 11.4. 索引和ORDER BY
- 11.5. 组合多个索引
- 11.6. 唯一索引
- 11.7. 表达式上的索引
- 11.8. 部分索引
- 11.9. 操作符类和操作符族
- 11.10. 索引和排序
- 11.11. 检查索引的使用
- Chapter 12. 全文检索
- 12.1. 介绍
- 12.2. 表和索引
- 12.3. 控制文本搜索
- 12.4. 附加功能
- 12.5. 解析器
- 12.6. 词典
- 12.7. 配置实例
- 12.8. 测试和调试文本搜索
- 12.9. GiST和GIN索引类型
- 12.10. psql支持
- 12.11. 限制
- 12.12. 来自8.3之前文本搜索的迁移
- Chapter 13. 并发控制
- 13.1. 介绍
- 13.2. 事务隔离
- 13.3. 明确锁定
- 13.4. 应用层数据完整性检查
- 13.5. 锁和索引
- Chapter 14. 性能提升技巧
- 14.1. 使用EXPLAIN
- 14.2. 规划器使用的统计信息
- 14.3. 用明确的JOIN控制规划器
- 14.4. 向数据库中添加记录
- 14.5. 非持久性设置
- III. 服务器管理
- Chapter 15. 源码安装
- 15.1. 简版
- 15.2. 要求
- 15.3. 获取源码
- 15.4. 安装过程
- 15.5. 安装后设置
- 15.6. 支持平台
- 15.7. 特定平台注意事项
- Chapter 16. Windows下用源代码安装
- 16.1. 用Visual C++或Microsoft Windows SDK编译
- 16.2. 用Visual C++或 Borland C++编译 libpq
- Chapter 17. 服务器设置和操作
- 17.1. PostgreSQL用户账户
- 17.2. 创建数据库集群
- 17.3. 启动数据库服务器
- 17.4. 管理内核资源
- 17.5. 关闭服务器
- 17.6. 升级一个 PostgreSQL 集群
- 17.7. 防止服务器欺骗
- 17.8. 加密选项
- 17.9. 用 SSL 进行安全的 TCP/IP 连接
- 17.10. 用SSH隧道进行安全 TCP/IP 连接
- 17.11. 在Windows上注册事件日志
- Chapter 18. 服务器配置
- 18.1. 设置参数
- 18.2. 文件位置
- 18.3. 连接和认证
- 18.4. 资源消耗
- 18.5. 预写式日志
- 18.6. 复制
- 18.7. 查询规划
- 18.8. 错误报告和日志
- 18.9. 运行时统计
- 18.10. 自动清理
- 18.11. 客户端连接缺省
- 18.12. 锁管理
- 18.13. 版本和平台兼容性
- 18.14. Error Handling
- 18.15. 预置选项
- 18.16. 自定义选项
- 18.17. 开发人员选项
- 18.18. 短选项
- Chapter 19. 用户认证
- 19.1. pg_hba.conf文件
- 19.2. 用户名映射
- 19.3. 认证方法
- 19.4. 用户认证
- Chapter 20. 数据库角色
- 20.1. 数据库角色
- 20.2. 角色属性
- 20.3. 角色成员
- 20.4. 函数和触发器安全
- Chapter 21. 管理数据库
- 21.1. 概述
- 21.2. 创建一个数据库
- 21.3. 模板数据库
- 21.4. 数据库配置
- 21.5. 删除数据库
- 21.6. 表空间
- Chapter 22. 区域
- 22.1. 区域支持
- 22.2. 排序规则支持
- 22.3. 字符集支持
- Chapter 23. 日常数据库维护工作
- 23.1. 日常清理
- 23.2. 经常重建索引
- 23.3. 日志文件维护
- Chapter 24. 备份与恢复
- 24.1. SQL转储
- 24.2. 文件系统级别备份
- 24.3. 在线备份以及即时恢复(PITR)
- Chapter 25. 高可用性与负载均衡,复制
- 25.1. 不同解决方案的比较
- 25.2. 日志传送备份服务器
- 25.3. 失效切换
- 25.4. 日志传送的替代方法
- 25.5. 热备
- Chapter 26. 恢复配置
- 26.1. 归档恢复设置
- 26.2. 恢复目标设置
- 26.3. 备用服务器设置
- Chapter 27. 监控数据库的活动
- 27.1. 标准Unix工具
- 27.2. 统计收集器
- 27.3. 查看锁
- 27.4. 动态跟踪
- Chapter 28. 监控磁盘使用情况
- 28.1. 判断磁盘的使用量
- 28.2. 磁盘满导致的失效
- Chapter 29. 可靠性和预写式日志
- 29.1. 可靠性
- 29.2. 预写式日志(WAL)
- 29.3. 异步提交
- 29.4. WAL 配置
- 29.5. WAL 内部
- Chapter 30. 回归测试
- 30.1. 运行测试
- 30.2. 测试评估
- 30.3. 平台相关的比较文件
- 30.4. 测试覆盖率检查
- IV. 客户端接口
- Chapter 31. libpq - C 库
- 31.1. 数据库连接控制函数
- 31.2. 连接状态函数
- 31.3. 命令执行函数
- 31.4. 异步命令处理
- 31.5. 逐行检索查询结果
- 31.6. 取消正在处理的查询
- 31.7. 捷径接口
- 31.8. 异步通知
- 31.9. 与COPY命令相关的函数
- 31.10. 控制函数
- 31.11. 各种函数
- 31.12. 注意信息处理
- 31.13. 事件系统
- 31.14. 环境变量
- 31.15. 口令文件
- 31.16. 连接服务的文件
- 31.17. LDAP查找连接参数
- 31.18. SSL 支持
- 31.19. 在多线程程序里的行为
- 31.20. 制作libpq程序
- 31.21. 例子程序
- Chapter 32. 大对象
- 32.1. 介绍
- 32.2. 实现特点
- 32.3. 客户端接口
- 32.4. 服务器端函数
- 32.5. 例子程序
- Chapter 33. ECPG - 在C中嵌入SQL
- 33.1. 概念
- 33.2. 管理数据库连接
- 33.3. 运行SQL命令
- 33.4. 使用宿主变量
- 33.5. 动态SQL
- 33.6. pgtypes 库
- 33.7. 使用描述符范围
- 33.8. 错误处理
- 33.9. 预处理器指令
- 33.10. 处理嵌入的SQL程序
- 33.11. 库函数
- 33.12. 大对象
- 33.13. C++应用程序
- 33.14. 嵌入的SQL命令
- ALLOCATE DESCRIPTOR
- CONNECT
- DEALLOCATE DESCRIPTOR
- DECLARE
- DESCRIBE
- DISCONNECT
- EXECUTE IMMEDIATE
- GET DESCRIPTOR
- OPEN
- PREPARE
- SET AUTOCOMMIT
- SET CONNECTION
- SET DESCRIPTOR
- TYPE
- VAR
- WHENEVER
- 33.15. Informix兼容模式
- 33.16. 内部
- Chapter 34. 信息模式
- 34.1. 关于这个模式
- 34.2. 数据类型
- 34.3. information_schema_catalog_name
- 34.4. administrable_role_authorizations
- 34.5. applicable_roles
- 34.6. attributes
- 34.7. character_sets
- 34.8. check_constraint_routine_usage
- 34.9. check_constraints
- 34.10. collations
- 34.11. collation_character_set_applicability
- 34.12. column_domain_usage
- 34.13. column_options
- 34.14. column_privileges
- 34.15. column_udt_usage
- 34.16. columns
- 34.17. constraint_column_usage
- 34.18. constraint_table_usage
- 34.19. data_type_privileges
- 34.20. domain_constraints
- 34.21. domain_udt_usage
- 34.22. domains
- 34.23. element_types
- 34.24. enabled_roles
- 34.25. foreign_data_wrapper_options
- 34.26. foreign_data_wrappers
- 34.27. foreign_server_options
- 34.28. foreign_servers
- 34.29. foreign_table_options
- 34.30. foreign_tables
- 34.31. key_column_usage
- 34.32. parameters
- 34.33. referential_constraints
- 34.34. role_column_grants
- 34.35. role_routine_grants
- 34.36. role_table_grants
- 34.37. role_udt_grants
- 34.38. role_usage_grants
- 34.39. routine_privileges
- 34.40. routines
- 34.41. schemata
- 34.42. sequences
- 34.43. sql_features
- 34.44. sql_implementation_info
- 34.45. sql_languages
- 34.46. sql_packages
- 34.47. sql_parts
- 34.48. sql_sizing
- 34.49. sql_sizing_profiles
- 34.50. table_constraints
- 34.51. table_privileges
- 34.52. tables
- 34.53. triggered_update_columns
- 34.54. triggers
- 34.55. udt_privileges
- 34.56. usage_privileges
- 34.57. user_defined_types
- 34.58. user_mapping_options
- 34.59. user_mappings
- 34.60. view_column_usage
- 34.61. view_routine_usage
- 34.62. view_table_usage
- 34.63. views
- V. 服务器端编程
- Chapter 35. 扩展SQL
- 35.1. 扩展性是如何实现的
- 35.2. PostgreSQL类型系统
- 35.3. 用户定义的函数
- 35.4. 查询语言(SQL)函数
- 35.5. 函数重载
- 35.6. 函数易失性范畴
- 35.7. 过程语言函数
- 35.8. 内部函数
- 35.9. C-语言函数
- 35.10. 用户定义聚集
- 35.11. 用户定义类型
- 35.12. 用户定义操作符
- 35.13. 操作符优化信息
- 35.14. 扩展索引接口
- 35.15. 包装相关对象到一个扩展
- 35.16. 扩展基础设施建设
- Chapter 36. 触发器
- 36.1. 触发器行为概述
- 36.2. 数据改变的可视性
- 36.3. 用C写触发器
- 36.4. 一个完整的触发器例子
- Chapter 37. 事件触发器
- 37.1. 事件触发器行为的概述
- 37.2. 事件触发器触发矩阵
- 37.3. 用C编写事件触发器函数
- 37.4. 一个完整的事件触发器的例子
- Chapter 38. 规则系统
- 38.1. 查询树
- 38.2. 视图和规则系统
- 38.3. 物化视图
- 38.4. 在 INSERT, UPDATE, 和 DELETE上的规则
- 38.5. 规则和权限
- 38.6. 规则和命令状态
- 38.7. 规则与触发器的比较
- Chapter 39. 过程语言
- 39.1. 安装过程语言
- Chapter 40. PL/pgSQL - SQL过程语言
- 40.1. 概述
- 40.2. PL/pgSQL的结构
- 40.3. 声明
- 40.4. 表达式
- 40.5. 基本语句
- 40.6. 控制结构
- 40.7. 游标
- 40.8. 错误和消息
- 40.9. 触发器过程
- 40.10. 在后台下的PL/pgSQL
- 40.11. 开发PL/pgSQL的一些提示
- 40.12. 从Oracle PL/SQL进行移植
- Chapter 41. PL/Tcl - Tcl 过程语言
- 41.1. 概述
- 41.2. PL/Tcl 函数和参数
- 41.3. PL/Tcl里的数据值
- 41.4. PL/Tcl里的全局量
- 41.5. 在PL/Tcl里访问数据库
- 41.6. PL/Tcl里的触发器过程
- 41.7. 模块和unknown的命令
- 41.8. Tcl 过程名字
- Chapter 42. PL/Perl - Perl 过程语言
- 42.1. PL/Perl 函数和参数
- 42.2. PL/Perl里的数据值
- 42.3. 内置函数
- 42.4. PL/Perl里的全局变量
- 42.5. 可信的和不可信的 PL/Perl
- 42.6. PL/Perl 触发器
- 42.7. 后台PL/Perl
- Chapter 43. PL/Python - Python 过程语言
- 43.1. Python 2 vs. Python 3
- 43.2. PL/Python Functions
- 43.3. Data Values
- 43.4. Sharing Data
- 43.5. Anonymous Code Blocks
- 43.6. Trigger Functions
- 43.7. Database Access
- 43.8. Explicit Subtransactions
- 43.9. Utility Functions
- 43.10. Environment Variables
- Chapter 44. 服务器编程接口
- 44.1. 接口函数
- SPI_connect
- SPI_finish
- SPI_push
- SPI_pop
- SPI_execute
- SPI_exec
- SPI_execute_with_args
- SPI_prepare
- SPI_prepare_cursor
- SPI_prepare_params
- SPI_getargcount
- SPI_getargtypeid
- SPI_is_cursor_plan
- SPI_execute_plan
- SPI_execute_plan_with_paramlist
- SPI_execp
- SPI_cursor_open
- SPI_cursor_open_with_args
- SPI_cursor_open_with_paramlist
- SPI_cursor_find
- SPI_cursor_fetch
- SPI_cursor_move
- SPI_scroll_cursor_fetch
- SPI_scroll_cursor_move
- SPI_cursor_close
- SPI_keepplan
- SPI_saveplan
- 44.2. 接口支持函数
- SPI_fname
- SPI_fnumber
- SPI_getvalue
- SPI_getbinval
- SPI_gettype
- SPI_gettypeid
- SPI_getrelname
- SPI_getnspname
- 44.3. 内存管理
- SPI_palloc
- SPI_repalloc
- SPI_pfree
- SPI_copytuple
- SPI_returntuple
- SPI_modifytuple
- SPI_freetuple
- SPI_freetuptable
- SPI_freeplan
- 44.4. 数据改变的可视性
- 44.5. 例子
- Chapter 45. 后台工作进程
- VI. 参考手册
- I. SQL 命令
- ABORT
- ALTER AGGREGATE
- ALTER COLLATION
- ALTER CONVERSION
- ALTER DATABASE
- ALTER DEFAULT PRIVILEGES
- ALTER DOMAIN
- ALTER EXTENSION
- ALTER EVENT TRIGGER
- ALTER FOREIGN DATA WRAPPER
- ALTER FOREIGN TABLE
- ALTER FUNCTION
- ALTER GROUP
- ALTER INDEX
- ALTER LANGUAGE
- ALTER LARGE OBJECT
- ALTER MATERIALIZED VIEW
- ALTER OPERATOR
- ALTER OPERATOR CLASS
- ALTER OPERATOR FAMILY
- ALTER ROLE
- ALTER RULE
- ALTER SCHEMA
- ALTER SEQUENCE
- ALTER SERVER
- ALTER TABLE
- ALTER TABLESPACE
- ALTER TEXT SEARCH CONFIGURATION
- ALTER TEXT SEARCH DICTIONARY
- ALTER TEXT SEARCH PARSER
- ALTER TEXT SEARCH TEMPLATE
- ALTER TRIGGER
- ALTER TYPE
- ALTER USER
- ALTER USER MAPPING
- ALTER VIEW
- ANALYZE
- BEGIN
- CHECKPOINT
- CLOSE
- CLUSTER
- COMMENT
- COMMIT
- COMMIT PREPARED
- COPY
- CREATE AGGREGATE
- CREATE CAST
- CREATE COLLATION
- CREATE CONVERSION
- CREATE DATABASE
- CREATE DOMAIN
- CREATE EXTENSION
- CREATE EVENT TRIGGER
- CREATE FOREIGN DATA WRAPPER
- CREATE FOREIGN TABLE
- CREATE FUNCTION
- CREATE GROUP
- CREATE INDEX
- CREATE LANGUAGE
- CREATE MATERIALIZED VIEW
- CREATE OPERATOR
- CREATE OPERATOR CLASS
- CREATE OPERATOR FAMILY
- CREATE ROLE
- CREATE RULE
- CREATE SCHEMA
- CREATE SEQUENCE
- CREATE SERVER
- CREATE TABLE
- CREATE TABLE AS
- CREATE TABLESPACE
- CREATE TEXT SEARCH CONFIGURATION
- CREATE TEXT SEARCH DICTIONARY
- CREATE TEXT SEARCH PARSER
- CREATE TEXT SEARCH TEMPLATE
- CREATE TRIGGER
- CREATE TYPE
- CREATE USER
- CREATE USER MAPPING
- CREATE VIEW
- DEALLOCATE
- DECLARE
- DELETE
- DISCARD
- DO
- DROP AGGREGATE
- DROP CAST
- DROP COLLATION
- DROP CONVERSION
- DROP DATABASE
- DROP DOMAIN
- DROP EXTENSION
- DROP EVENT TRIGGER
- DROP FOREIGN DATA WRAPPER
- DROP FOREIGN TABLE
- DROP FUNCTION
- DROP GROUP
- DROP INDEX
- DROP LANGUAGE
- DROP MATERIALIZED VIEW
- DROP OPERATOR
- DROP OPERATOR CLASS
- DROP OPERATOR FAMILY
- DROP OWNED
- DROP ROLE
- DROP RULE
- DROP SCHEMA
- DROP SEQUENCE
- DROP SERVER
- DROP TABLE
- DROP TABLESPACE
- DROP TEXT SEARCH CONFIGURATION
- DROP TEXT SEARCH DICTIONARY
- DROP TEXT SEARCH PARSER
- DROP TEXT SEARCH TEMPLATE
- DROP TRIGGER
- DROP TYPE
- DROP USER
- DROP USER MAPPING
- DROP VIEW
- END
- EXECUTE
- EXPLAIN
- FETCH
- GRANT
- INSERT
- LISTEN
- LOAD
- LOCK
- MOVE
- NOTIFY
- PREPARE
- PREPARE TRANSACTION
- REASSIGN OWNED
- REFRESH MATERIALIZED VIEW
- REINDEX
- RELEASE SAVEPOINT
- RESET
- REVOKE
- ROLLBACK
- ROLLBACK PREPARED
- ROLLBACK TO SAVEPOINT
- SAVEPOINT
- SECURITY LABEL
- SELECT
- SELECT INTO
- SET
- SET CONSTRAINTS
- SET ROLE
- SET SESSION AUTHORIZATION
- SET TRANSACTION
- SHOW
- START TRANSACTION
- TRUNCATE
- UNLISTEN
- UPDATE
- VACUUM
- VALUES
- II. PostgreSQL 客户端应用程序
- clusterdb
- createdb
- createlang
- createuser
- dropdb
- droplang
- dropuser
- ecpg
- pg_basebackup
- pg_config
- pg_dump
- pg_dumpall
- pg_isready
- pg_receivexlog
- pg_restore
- psql
- reindexdb
- vacuumdb
- III. PostgreSQL 服务器应用程序
- initdb
- pg_controldata
- pg_ctl
- pg_resetxlog
- postgres
- postmaster
- VII. 内部
- Chapter 46. PostgreSQL内部概述
- 46.1. 查询经过的路径
- 46.2. 连接是如何建立起来的
- 46.3. 分析器阶段
- 46.4. PostgreSQL规则系统
- 46.5. 规划器/优化器
- 46.6. 执行器
- Chapter 47. 系统表
- 47.1. 概述
- 47.2. pg_aggregate
- 47.3. pg_am
- 47.4. pg_amop
- 47.5. pg_amproc
- 47.6. pg_attrdef
- 47.7. pg_attribute
- 47.8. pg_authid
- 47.9. pg_auth_members
- 47.10. pg_cast
- 47.11. pg_class
- 47.12. pg_event_trigger
- 47.13. pg_constraint
- 47.14. pg_collation
- 47.15. pg_conversion
- 47.16. pg_database
- 47.17. pg_db_role_setting
- 47.18. pg_default_acl
- 47.19. pg_depend
- 47.20. pg_description
- 47.21. pg_enum
- 47.22. pg_extension
- 47.23. pg_foreign_data_wrapper
- 47.24. pg_foreign_server
- 47.25. pg_foreign_table
- 47.26. pg_index
- 47.27. pg_inherits
- 47.28. pg_language
- 47.29. pg_largeobject
- 47.30. pg_largeobject_metadata
- 47.31. pg_namespace
- 47.32. pg_opclass
- 47.33. pg_operator
- 47.34. pg_opfamily
- 47.35. pg_pltemplate
- 47.36. pg_proc
- 47.37. pg_range
- 47.38. pg_rewrite
- 47.39. pg_seclabel
- 47.40. pg_shdepend
- 47.41. pg_shdescription
- 47.42. pg_shseclabel
- 47.43. pg_statistic
- 47.44. pg_tablespace
- 47.45. pg_trigger
- 47.46. pg_ts_config
- 47.47. pg_ts_config_map
- 47.48. pg_ts_dict
- 47.49. pg_ts_parser
- 47.50. pg_ts_template
- 47.51. pg_type
- 47.52. pg_user_mapping
- 47.53. 系统视图
- 47.54. pg_available_extensions
- 47.55. pg_available_extension_versions
- 47.56. pg_cursors
- 47.57. pg_group
- 47.58. pg_indexes
- 47.59. pg_locks
- 47.60. pg_matviews
- 47.61. pg_prepared_statements
- 47.62. pg_prepared_xacts
- 47.63. pg_roles
- 47.64. pg_rules
- 47.65. pg_seclabels
- 47.66. pg_settings
- 47.67. pg_shadow
- 47.68. pg_stats
- 47.69. pg_tables
- 47.70. pg_timezone_abbrevs
- 47.71. pg_timezone_names
- 47.72. pg_user
- 47.73. pg_user_mappings
- 47.74. pg_views
- Chapter 48. 前/后端协议
- 48.1. 概要
- 48.2. 消息流
- 48.3. 流复制协议
- 48.4. 消息数据类型
- 48.5. 消息格式
- 48.6. 错误和通知消息字段
- 48.7. 自协议 2.0 以来的变化的概述
- Chapter 49. PostgreSQL 编码约定
- 49.1. 格式
- 49.2. 报告服务器里的错误
- 49.3. 错误消息风格指导
- Chapter 50. 本地语言支持
- 50.1. 寄语翻译家
- 50.2. 寄语程序员
- Chapter 51. 书写一个过程语言处理器
- Chapter 52. 写一个外数据包
- 52.1. 外数据封装函数
- 52.2. 外数据封装回调程序
- 52.3. 外数据封装辅助函数
- 52.4. 外数据封装查询规划
- Chapter 53. 基因查询优化器
- 53.1. 作为复杂优化问题的查询处理
- 53.2. 基因算法
- 53.3. PostgreSQL 里的基因查询优化(GEQO)
- 53.4. 进一步阅读
- Chapter 54. 索引访问方法接口定义
- 54.1. 索引的系统表记录
- 54.2. 索引访问方法函数
- 54.3. 索引扫描
- 54.4. 索引锁的考量
- 54.5. 索引唯一性检查
- 54.6. 索引开销估计函数
- Chapter 55. GiST索引
- 55.1. 介绍
- 55.2. 扩展性
- 55.3. 实现
- 55.4. 例
- Chapter 56. SP-GiST索引
- 56.1. 介绍
- 56.2. 扩展性
- 56.3. 实现
- 56.4. 例
- Chapter 57. GIN索引
- 57.1. 介绍
- 57.2. 扩展性
- 57.3. 实现
- 57.4. GIN提示与技巧
- 57.5. 限制
- 57.6. 例子
- Chapter 58. 数据库物理存储
- 58.1. 数据库文件布局
- 58.2. TOAST
- 58.3. 自由空间映射
- 58.4. 可见映射
- 58.5. 初始化分支
- 58.6. 数据库分页文件
- Chapter 59. BKI后端接口
- 59.1. BKI 文件格式
- 59.2. BKI 命令
- 59.3. 系统初始化的BKI文件的结构
- 59.4. 例子
- Chapter 60. 规划器如何使用统计信息
- 60.1. 行预期的例子
- VIII. 附录
- Appendix A. PostgreSQL 错误代码
- Appendix B. 日期/时间支持
- B.1. 日期/时间输入解析
- B.2. 日期/时间关键字
- B.3. 日期/时间配置文件
- B.4. 单位历史
- Appendix C. SQL关键字
- Appendix D. SQL兼容性
- D.1. 支持的特性
- D.2. 不支持的特性
- Appendix E. 版本说明
- E.1. 版本 9.3.1
- E.2. 版本 9.3
- E.3. 版本9.2.5
- E.4. 版本9.2.4
- E.5. 版本9.2.3
- E.6. 版本9.2.2
- E.7. 版本9.2.1
- E.8. 版本9.2
- E.9. 发布9.1.10
- E.10. 发布9.1.9
- E.11. 发布9.1.8
- E.12. 发布9.1.7
- E.13. 发布9.1.6
- E.14. 发布9.1.5
- E.15. 发布9.1.4
- E.16. 发布9.1.3
- E.17. 发布9.1.2
- E.18. 发布9.1.1
- E.19. 发布9.1
- E.20. 版本 9.0.14
- E.21. 版本 9.0.13
- E.22. 版本 9.0.12
- E.23. 版本 9.0.11
- E.24. 版本 9.0.10
- E.25. 版本 9.0.9
- E.26. 版本 9.0.8
- E.27. 版本 9.0.7
- E.28. 版本 9.0.6
- E.29. 版本 9.0.5
- E.30. 版本 9.0.4
- E.31. 版本 9.0.3
- E.32. 版本 9.0.2
- E.33. 版本 9.0.1
- E.34. 版本 9.0
- E.35. 发布8.4.18
- E.36. 发布8.4.17
- E.37. 发布8.4.16
- E.38. 发布8.4.15
- E.39. 发布8.4.14
- E.40. 发布8.4.13
- E.41. 发布8.4.12
- E.42. 发布8.4.11
- E.43. 发布8.4.10
- E.44. 发布8.4.9
- E.45. 发布8.4.8
- E.46. 发布8.4.7
- E.47. 发布8.4.6
- E.48. 发布8.4.5
- E.49. 发布8.4.4
- E.50. 发布8.4.3
- E.51. 发布8.4.2
- E.52. 发布8.4.1
- E.53. 发布8.4
- E.54. 发布8.3.23
- E.55. 发布8.3.22
- E.56. 发布8.3.21
- E.57. 发布8.3.20
- E.58. 发布8.3.19
- E.59. 发布8.3.18
- E.60. 发布8.3.17
- E.61. 发布8.3.16
- E.62. 发布8.3.15
- E.63. 发布8.3.14
- E.64. 发布8.3.13
- E.65. 发布8.3.12
- E.66. 发布8.3.11
- E.67. 发布8.3.10
- E.68. 发布8.3.9
- E.69. 发布8.3.8
- E.70. 发布8.3.7
- E.71. 发布8.3.6
- E.72. 发布8.3.5
- E.73. 发布8.3.4
- E.74. 发布8.3.3
- E.75. 发布8.3.2
- E.76. 发布8.3.1
- E.77. 发布8.3
- E.78. 版本 8.2.23
- E.79. 版本 8.2.22
- E.80. 版本 8.2.21
- E.81. 版本 8.2.20
- E.82. 版本 8.2.19
- E.83. 版本 8.2.18
- E.84. 版本 8.2.17
- E.85. 版本 8.2.16
- E.86. 版本 8.2.15
- E.87. 版本 8.2.14
- E.88. 版本 8.2.13
- E.89. 版本 8.2.12
- E.90. 版本 8.2.11
- E.91. 版本 8.2.10
- E.92. 版本 8.2.9
- E.93. 版本 8.2.8
- E.94. 版本 8.2.7
- E.95. 版本 8.2.6
- E.96. 版本 8.2.5
- E.97. 版本 8.2.4
- E.98. 版本 8.2.3
- E.99. 版本 8.2.2
- E.100. 版本 8.2.1
- E.101. 版本 8.2
- E.102. 版本 8.1.23
- E.103. 版本 8.1.22
- E.104. 版本 8.1.21
- E.105. 版本 8.1.20
- E.106. 版本 8.1.19
- E.107. 版本 8.1.18
- E.108. 版本 8.1.17
- E.109. 版本 8.1.16
- E.110. 版本 8.1.5
- E.111. 版本 8.1.14
- E.112. 版本 8.1.13
- E.113. 版本 8.1.12
- E.114. 版本 8.1.11
- E.115. 版本 8.1.10
- E.116. 版本 8.1.9
- E.117. 版本 8.1.8
- E.118. 版本 8.1.7
- E.119. 版本 8.1.6
- E.120. 版本 8.1.5
- E.121. 版本 8.1.4
- E.122. 版本 8.1.3
- E.123. 版本 8.1.2
- E.124. 版本 8.1.1
- E.125. 版本 8.1
- E.126. 版本 8.0.26
- E.127. 版本 8.0.25
- E.128. 版本 8.0.24
- E.129. 版本 8.0.23
- E.130. 版本 8.0.22
- E.131. 版本 8.0.21
- E.132. 版本 8.0.20
- E.133. 版本 8.0.19
- E.134. 版本 8.0.18
- E.135. 版本 8.0.17
- E.136. 版本 8.0.16
- E.137. 版本 8.0.15
- E.138. 版本 8.0.14
- E.139. 版本 8.0.13
- E.140. 版本 8.0.12
- E.141. 版本 8.0.11
- E.142. 版本 8.0.10
- E.143. 版本 8.0.9
- E.144. 版本 8.0.8
- E.145. 版本 8.0.7
- E.146. 版本 8.0.6
- E.147. 版本 8.0.5
- E.148. 版本 8.0.4
- E.149. 版本 8.0.3
- E.150. 版本 8.0.2
- E.151. 版本 8.0.1
- E.152. 版本 8.0.0
- E.153. 版本 7.4.30
- E.154. 版本 7.4.29
- E.155. 版本 7.4.28
- E.156. 版本 7.4.27
- E.157. 版本 7.4.26
- E.158. 版本 7.4.25
- E.159. 版本 7.4.24
- E.160. 版本 7.4.23
- E.161. 版本 7.4.22
- E.162. 版本 7.4.21
- E.163. 版本 7.4.20
- E.164. 版本 7.4.19
- E.165. 版本 7.4.18
- E.166. 版本 7.4.17
- E.167. 版本 7.4.16
- E.168. 版本 7.4.15
- E.169. 版本 7.4.14
- E.170. 版本 7.4.13
- E.171. 版本 7.4.12
- E.172. 版本 7.4.11
- E.173. 版本 7.4.10
- E.174. 版本 7.4.9
- E.175. 版本 7.4.8
- E.176. 版本 7.4.7
- E.177. 版本 7.4.6
- E.178. 版本 7.4.3
- E.179. 版本 7.4.4
- E.180. 版本 7.4.3
- E.181. 版本 7.4.2
- E.182. 版本 7.4.1
- E.183. 版本 7.4
- E.184. 版本 7.3.21
- E.185. 版本 7.3.20
- E.186. 版本 7.3.19
- E.187. 版本 7.3.18
- E.188. 版本 7.3.17
- E.189. 版本 7.3.16
- E.190. 版本 7.3.15
- E.191. 版本 7.3.14
- E.192. 版本 7.3.13
- E.193. 版本 7.3.12
- E.194. 版本 7.3.11
- E.195. 版本 7.3.10
- E.196. 版本 7.3.9
- E.197. 版本 7.3.8
- E.198. 版本 7.3.7
- E.199. 版本 7.3.6
- E.200. 版本 7.3.5
- E.201. 版本 7.3.4
- E.202. 版本 7.3.3
- E.203. 版本 7.3.2
- E.204. 版本 7.3.1
- E.205. 版本 7.3
- E.206. 版本 7.2.8
- E.207. 版本 7.2.7
- E.208. 版本 7.2.6
- E.209. 版本 7.2.5
- E.210. 版本 7.2.4
- E.211. 版本 7.2.3
- E.212. 版本 7.2.2
- E.213. 版本 7.2.1
- E.214. 版本 7.2
- E.215. 版本 7.1.3
- E.216. 版本 7.1.2
- E.217. 版本 7.1.1
- E.218. 版本 7.1
- E.219. 版本 7.0.3
- E.220. 版本 7.0.2
- E.221. 版本 7.0.1
- E.222. 版本 7.0
- E.223. 版本 6.5.3
- E.224. 版本 6.5.2
- E.225. 版本 6.5.1
- E.226. 版本 6.5
- E.227. 版本 6.4.2
- E.228. 版本 6.4.1
- E.229. 版本 6.4
- E.230. 版本 6.3.2
- E.231. 版本 6.3.1
- E.232. 版本 6.3
- E.233. 版本 6.2.1
- E.234. 版本 6.2
- E.235. 版本 6.1.1
- E.236. 版本 6.1
- E.237. 版本 6.0
- E.238. 版本 1.09
- E.239. 版本 1.02
- E.240. 版本 1.01
- E.241. 版本 1.0
- E.242. Postgres95 版本 0.03
- E.243. Postgres95 版本 0.02
- E.244. Postgres95 版本 0.01
- Appendix F. 额外提供的模块
- F.1. adminpack
- F.2. auth_delay
- F.3. auto_explain
- F.4. btree_gin
- F.5. btree_gist
- F.6. chkpass
- F.7. citext
- F.8. cube
- F.9. dblink
- dblink_connect
- dblink_connect_u
- dblink_disconnect
- dblink
- dblink_exec
- dblink_open
- dblink_fetch
- dblink_close
- dblink_get_connections
- dblink_error_message
- dblink_send_query
- dblink_is_busy
- dblink_get_notify
- dblink_get_result
- dblink_cancel_query
- dblink_get_pkey
- dblink_build_sql_insert
- dblink_build_sql_delete
- dblink_build_sql_update
- F.10. dict_int
- F.11. dict_xsyn
- F.12. dummy_seclabel
- F.13. earthdistance
- F.14. file_fdw
- F.15. fuzzystrmatch
- F.16. hstore
- F.17. intagg
- F.18. intarray
- F.19. isn
- F.20. lo
- F.21. ltree
- F.22. pageinspect
- F.23. passwordcheck
- F.24. pg_buffercache
- F.25. pgcrypto
- F.26. pg_freespacemap
- F.27. pgrowlocks
- F.28. pg_stat_statements
- F.29. pgstattuple
- F.30. pg_trgm
- F.31. postgres_fdw
- F.32. seg
- F.33. sepgsql
- F.34. spi
- F.35. sslinfo
- F.36. tablefunc
- F.37. tcn
- F.38. test_parser
- F.39. tsearch2
- F.40. unaccent
- F.41. uuid-ossp
- F.42. xml2
- Appendix G. 额外提供的程序
- G.1. 客户端应用程序
- oid2name
- pgbench
- vacuumlo
- G.2. 服务器端应用程序
- pg_archivecleanup
- pg_standby
- pg_test_fsync
- pg_test_timing
- pg_upgrade
- pg_xlogdump
- Appendix H. 外部项目
- H.1. 客户端接口
- H.2. 管理工具
- H.3. 过程语言
- H.4. 扩展
- Appendix I. 源代码库
- I.1. 获得源代码通过Git
- Appendix J. 文档
- J.1. DocBook
- J.2. 工具集
- J.3. 制作文档
- J.4. 文档写作
- J.5. 风格指导
- Appendix K. 首字母缩略词
- 参考书目
- Index