受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

Appendix F. 额外提供的模块与扩展

Table of Contents

F.1. amcheck
F.1.1. 函数
F.1.2. 可选的heapallindexed验证
F.1.3. 有效使用amcheck
F.1.4. 修复损坏
F.2. auth_delay — 在认证失败时暂停
F.2.1. 配置参数
F.2.2. 作者
F.3. auto_explain
F.3.1. 配置参数
F.3.2. 示例
F.3.3. 作者
F.4. bloom
F.4.1. 参数
F.4.2. 示例
F.4.3. 操作符类接口
F.4.4. 限制
F.4.5. 作者
F.5. btree_gin
F.5.1. 用法示例
F.5.2. 作者
F.6. btree_gist
F.6.1. 用法示例
F.6.2. 作者
F.7. citext — 大小写不敏感的字符串类型
F.7.1. 原理
F.7.2. 如何使用
F.7.3. 字符串比较行为
F.7.4. 限制
F.7.5. 作者
F.8. cube — 多维立方体数据类型
F.8.1. 语法
F.8.2. 精度
F.8.3. 用法
F.8.4. 默认规则
F.8.5. 注意
F.8.6. 致谢
F.9. dblink
dblink_connect — 打开到远程数据库的持久连接
dblink_connect_u — 不安全地打开到远程数据库的持久连接
dblink_disconnect — 关闭到远程数据库的持久连接
dblink — 在远程数据库中执行查询
dblink_exec — 在远程数据库中执行命令
dblink_open — 在远程数据库中打开游标
dblink_fetch — 返回远程数据库中已打开游标的行
dblink_close — 关闭远程数据库中的游标
dblink_get_connections — 返回所有打开的命名 dblink 连接的名称
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 — 使用本地元组构造 INSERT 语句,并用提供的替代值替换主键字段值
dblink_build_sql_delete — 使用提供的主键字段值构造 DELETE 语句
dblink_build_sql_update — 使用本地元组构造 UPDATE 语句,并用提供的替代值替换主键字段值
F.10. dict_int — 用于整数的示例全文搜索词典
F.10.1. 配置
F.10.2. 用法
F.11. dict_xsyn — 示例同义词全文检索词典
F.11.1. 配置
F.11.2. 用法
F.12. earthdistance — 计算大圆距离
F.12.1. 基于立方体的地球距离
F.12.2. 基于点的地球距离
F.13. file_fdw
F.14. fuzzystrmatch — 确定字符串的相似性和距离
F.14.1. Soundex
F.14.2. Daitch-Mokotoff Soundex
F.14.3. Levenshtein
F.14.4. Metaphone
F.14.5. Double Metaphone
F.15. hstore
F.15.1. hstore 外部表示
F.15.2. hstore 操作符和函数
F.15.3. 索引
F.15.4. 示例
F.15.5. 统计信息
F.15.6. 兼容性
F.15.7. 转换
F.15.8. 作者
F.16. intagg — 整数聚合器和枚举器
F.16.1. 函数
F.16.2. 使用示例
F.17. intarray
F.17.1. intarray 函数和操作符
F.17.2. 索引支持
F.17.3. 示例
F.17.4. 基准测试
F.17.5. 作者
F.18. isn — 国际标准编号(ISBN、EAN、UPC 等)的数据类型
F.18.1. 数据类型
F.18.2. 类型转换
F.18.3. 函数和操作符
F.18.4. 配置参数
F.18.5. 示例
F.18.6. 参考文献
F.18.7. 作者
F.19. lo — 管理大对象
F.19.1. 原理
F.19.2. 如何使用
F.19.3. 限制
F.19.4. 作者
F.20. ltree
F.20.1. 定义
F.20.2. 操作符和函数
F.20.3. 索引
F.20.4. 示例
F.20.5. 转换
F.20.6. 作者
F.21. old_snapshot
F.21.1. 函数
F.22. pageinspect
F.22.1. 通用函数
F.22.2. 堆函数
F.22.3. B-树函数
F.22.4. BRIN 函数
F.22.5. GIN 函数
F.22.6. GiST 函数
F.22.7. 哈希函数
F.23. passwordcheck
F.23.1. 配置参数
F.24. pg_buffercache
F.24.1. pg_buffercache 视图
F.24.2. pg_buffercache_numa 视图
F.24.3. pg_buffercache_summary() 函数
F.24.4. pg_buffercache_usage_counts() 函数
F.24.5. pg_buffercache_evict() 函数
F.24.6. pg_buffercache_evict_relation() 函数
F.24.7. pg_buffercache_evict_all() 函数
F.24.8. 示例输出
F.24.9. 作者
F.25. pgcrypto
F.25.1. 通用哈希函数
F.25.2. 密码哈希函数
F.25.3. PGP 加密函数
F.25.4. 原始加密函数
F.25.5. 随机数据函数
F.25.6. 注意事项
F.25.7. 作者
F.26. pg_freespacemap
F.26.1. 函数
F.26.2. 示例输出
F.26.3. 作者
F.27. pg_prewarm — 将关系数据预热到缓冲区缓存中
F.27.1. 函数
F.27.2. 配置参数
F.27.3. 作者
F.28. pgrowlocks — 显示表的行锁信息
F.28.1. 概述
F.28.2. 示例输出
F.28.3. 作者
F.29. pg_stat_statements
F.29.1. pg_stat_statements 视图
F.29.2. pg_stat_statements_info 视图
F.29.3. 函数
F.29.4. 配置参数
F.29.5. 示例输出
F.29.6. 作者
F.30. pgstattuple — 获取元组级统计信息
F.30.1. 函数
F.30.2. 作者
F.31. pg_surgery
F.31.1. 函数
F.31.2. 作者
F.32. pg_trgm
F.32.1. 三元组(Trigram 或 Trigraph)概念
F.32.2. 函数和操作符
F.32.3. GUC 参数
F.32.4. 索引支持
F.32.5. 文本搜索集成
F.32.6. 参考
F.32.7. 作者
F.33. pg_visibility
F.33.1. 函数
F.33.2. 作者
F.34. postgres_fdw
F.34.1. postgres_fdw 的 FDW 选项
F.34.2. 函数
F.34.3. 连接管理
F.34.4. 事务管理
F.34.5. 远程查询优化
F.34.6. 远程查询执行环境
F.34.7. 跨版本兼容性
F.34.8. 等待事件
F.34.9. 配置参数
F.34.10. 示例
F.34.11. 作者
F.35. seg — 用于线段或浮点区间的数据类型
F.35.1. 原理
F.35.2. 语法
F.35.3. 精度
F.35.4. 用法
F.35.5. 注意
F.35.6. 致谢
F.36. sepgsql — 基于 SELinux 标签的强制访问控制(MAC)安全模块
F.36.1. 概述
F.36.2. 安装
F.36.3. 回归测试
F.36.4. GUC 参数
F.36.5. 特性
F.36.6. sepgsql 函数
F.36.7. 限制
F.36.8. 外部资源
F.36.9. 作者
F.37. spi
F.37.1. refint — 用于实现引用完整性的函数
F.37.2. autoinc — 用于字段自动递增的函数
F.37.3. insert_username — 用于跟踪谁修改了表的函数
F.37.4. moddatetime — 用于跟踪最后修改时间的函数
F.38. sslinfo
F.38.1. 提供的函数
F.38.2. 作者
F.39. tablefunc
F.39.1. 提供的函数
F.39.2. 作者
F.40. tcn
F.41. test_decoding
F.42. tsm_system_rows
F.42.1. 示例
F.43. tsm_system_time
F.43.1. 示例
F.44. unaccent
F.44.1. 配置
F.44.2. 用法
F.44.3. 函数
F.45. uuid-ossp
F.45.1. uuid-ossp 函数
F.45.2. 构建uuid-ossp
F.45.3. 作者
F.46. xml2 — XPath 查询与 XSLT 功能
F.46.1. 弃用说明
F.46.2. 函数说明
F.46.3. xpath_table
F.46.4. XSLT 函数
F.46.5. 作者

本附录与下一附录包含有关 PostgreSQL 发行版中 contrib 目录中可选组件的信息。 这些组件包括移植工具、分析实用程序,以及不属于 PostgreSQL 核心系统的 插件功能。之所以将它们单独提供,主要是因为它们面向的受众有限, 或者实验性太强,不适合作为主源码树的一部分。但这并不影响它们的实用性。

本附录介绍位于 contrib 中的扩展以及其他服务器插件模块库。 Appendix G 介绍实用程序。

从源码发行版构建时,除非构建 world 目标 (见 Step 2),否则这些可选组件不会自动构建。 你可以在已配置好的源码树的 contrib 目录中运行:

make
make install

以构建并安装所有组件;若只想构建并安装某个选定的模块, 则可在该模块的子目录中执行同样的命令。 许多模块都带有回归测试,可以在安装前运行:

make check

或在 PostgreSQL 服务器已经运行后运行:

make installcheck

如果你使用的是预打包版本的 PostgreSQL, 这些组件通常会作为单独的子包提供,例如 postgresql-contrib

许多组件提供新的用户定义函数、操作符或类型,并将其打包为 扩展。 安装代码后,要使用其中某个扩展,就需要在数据库系统中注册新的 SQL 对象。 这可通过执行 CREATE EXTENSION 命令完成。 在一个新建的数据库中,你可以直接执行:

CREATE EXTENSION extension_name;

该命令只会在当前数据库中注册这些新的 SQL 对象,因此需要在每个希望使用该 扩展功能的数据库中运行它。另一种做法是在 template1 数据库中运行它,这样该扩展默认会被复制到随后创建的数据库中。

对于所有扩展,除非该扩展被视为 trusted,否则 CREATE EXTENSION 命令必须由数据库超级用户执行。 受信任扩展可以由任何在当前数据库上具有 CREATE 权限 的用户执行。下文各节会标明哪些扩展是受信任的。一般来说,受信任扩展是那 些不能提供对数据库外部功能访问的扩展。

在默认安装中,以下扩展是受信任的:

btree_gin fuzzystrmatch ltree tcn
btree_gist hstore pgcrypto tsm_system_rows
citext intarray pg_trgm tsm_system_time
cube isn seg unaccent
dict_int lo tablefunc uuid-ossp

许多扩展允许你将其对象安装到所选的模式中。要这样做,请在 CREATE EXTENSION 命令中加入 SCHEMA schema_name。 默认情况下,这些对象会被放入当前的创建目标模式,而该模式默认是 public

但请注意,其中有些组件并不是这种意义上的 扩展, 而是通过其他方式加载到服务器中,例如借助 shared_preload_libraries。 详情见各组件文档。

F.1. amcheck #

amcheck模块提供了一组函数,可用于验证关系结构的逻辑一致性。

B-树检查函数会验证特定关系表示结构中的多种不变式。 索引扫描以及其他重要操作背后的访问方法函数是否正确,依赖于这些不变式始终成立。 例如,某些函数除其他事项外,还会验证所有 B-树页面中的项都按逻辑顺序排列 (例如,对于text上的 B-树索引,索引元组应当按排序规则定义的词法顺序排列)。 如果这种特定不变式由于某种原因不再成立,那么受影响页面上的二分查找就可能错误地引导索引扫描, 从而使 SQL 查询返回错误答案。如果结构看起来有效,就不会引发错误。 这些检查函数运行期间,search_path会被临时改为 pg_catalog, pg_temp

验证工作使用的过程与索引扫描本身所使用的过程相同,而这些过程可能是用户定义的操作符类代码。 例如,B-树索引验证依赖于一个或多个 B-树支持函数 1 例程执行的比较。 关于操作符类支持函数的细节,见Section 36.16.3

与通过抛出错误来报告损坏的 B-树检查函数不同,堆检查函数 verify_heapam会检查一个表,并尝试返回一组行, 每检测到一处损坏就返回一行。尽管如此,如果 verify_heapam所依赖的设施本身已经损坏, 该函数也可能无法继续执行,而改为抛出错误。

执行amcheck函数的权限可以授予非超级用户,但在授予这些权限之前, 应认真考虑数据安全和隐私方面的顾虑。虽然这些函数生成的损坏报告关注的重点, 与其说是损坏数据的内容,不如说是该数据的结构以及所发现损坏的性质,但攻击者一旦获得执行这些函数的权限, 尤其是在还能诱发损坏的情况下,仍可能从这类消息中推断出某些数据本身的信息。

F.1.1. 函数 #

bt_index_check(index regclass, heapallindexed boolean) returns void

bt_index_check测试其目标 B-树索引是否满足多种不变式。示例用法如下:

test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique),
               c.relname,
               c.relpages
FROM pg_index i
JOIN pg_opclass op ON i.indclass[0] = op.oid
JOIN pg_am am ON op.opcmethod = am.oid
JOIN pg_class c ON i.indexrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog'
-- Don't check temp tables, which may be from another session:
AND c.relpersistence != 't'
-- Function may throw an error when this is omitted:
AND c.relkind = 'i' AND i.indisready AND i.indisvalid
ORDER BY c.relpages DESC LIMIT 10;
 bt_index_check |             relname             | relpages
----------------+---------------------------------+----------
                | pg_depend_reference_index       |       43
                | pg_depend_depender_index        |       40
                | pg_proc_proname_args_nsp_index  |       31
                | pg_description_o_c_o_index      |       21
                | pg_attribute_relid_attnam_index |       14
                | pg_proc_oid_index               |       10
                | pg_attribute_relid_attnum_index |        9
                | pg_amproc_fam_proc_index        |        5
                | pg_amop_opr_fam_index           |        5
                | pg_amop_fam_strat_index         |        5
(10 rows)

本例展示了一个会话,它对数据库test中最大的 10 个系统目录索引执行验证。 对其中属于唯一索引的那一部分,还要求验证所有堆元组在索引中都有对应的索引元组。 由于没有引发错误,因此所有受测索引看起来都具有逻辑一致性。 当然,也很容易把这个查询改成对数据库中每一个支持验证的索引调用 bt_index_check

bt_index_check会在目标索引及其所属的堆关系上获取 AccessShareLock。这种锁模式与简单 SELECT语句在关系上获取的锁模式相同。 bt_index_check不会验证跨越父子关系的不变式, 但如果heapallindexedtrue, 它会验证所有堆元组在索引中都有对应的索引元组。 当在线生产环境中需要一种例行的、轻量级的损坏检查时, bt_index_check通常能在验证彻底程度与对应用性能、可用性的影响之间提供最佳权衡。

bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void

bt_index_parent_check测试其目标 B-树索引是否满足多种不变式。 如果可选参数heapallindexedtrue, 该函数还会验证索引中是否包含所有本应出现的堆元组。 如果可选参数rootdescendtrue, 则会对每个元组都从根页重新搜索一次,从而在叶子层重新定位这些元组。 bt_index_parent_check能够执行的检查, 是bt_index_check所能执行检查的超集。 可以把bt_index_parent_check看作 bt_index_check更彻底的变体: 与bt_index_check不同, bt_index_parent_check还会检查跨越父子关系的不变式, 包括验证索引结构中不存在缺失的下行链接。 如果发现逻辑不一致或其他问题,该函数就会引发错误。

bt_index_parent_check要求在目标索引上持有 ShareLock(并且在堆关系上也会获取 ShareLock)。这些锁会阻止 INSERTUPDATE以及 DELETE命令并发修改数据。 这些锁还会阻止底层关系被并发VACUUM处理,以及执行所有其他实用命令。 注意,该函数只在运行期间持有这些锁,而不是在整个事务期间持有。

bt_index_parent_check所做的额外验证,更有可能检测出各种异常情形。 这些情形可能涉及被检查索引所使用的 B-树操作符类实现错误, 或者假设存在的、底层 B-树索引访问方法代码中尚未发现的缺陷。 请注意,与bt_index_check不同, 在启用热备模式时(即在只读物理副本上),不能使用 bt_index_parent_check

Tip

bt_index_checkbt_index_parent_check都会以 DEBUG1DEBUG2严重性级别输出关于验证过程的日志消息。 这些消息提供了验证过程的详细信息,可能会让 PostgreSQL开发者感兴趣。高级用户也可能觉得这些信息有帮助, 因为一旦验证确实检测到不一致,它们就能提供额外的上下文。若在交互式 psql会话中于运行验证查询之前执行:

SET client_min_messages = DEBUG1;

则会以一个便于掌控的细节层次显示关于验证进度的消息。

verify_heapam(relation regclass, on_error_stop boolean, check_toast boolean, skip text, startblock bigint, endblock bigint, blkno OUT bigint, offnum OUT integer, attnum OUT integer, msg OUT text) returns setof record

检查一个表是否存在结构损坏或逻辑损坏。 结构损坏是指关系中的页面包含格式无效的数据; 逻辑损坏则是指页面在结构上有效,但与数据库集簇的其余部分不一致。

支持以下可选参数:

on_error_stop

如果为真,则一旦在某个块中发现任何损坏,检查会在该块末尾停止。

默认为假。

check_toast

如果为真,则会根据目标关系的 TOAST 表检查 toasted 值。

众所周知,这个选项比较慢。另外,如果 TOAST 表或其索引本身已损坏, 使用 toast 值对其进行检查在理论上可能会使服务器崩溃,尽管在很多情况下只会产生一个错误。

默认为假。

skip

如果不是none,则会按指定方式跳过那些被标记为全可见或全冻结的块。 有效选项为all-visibleall-frozennone

默认为none

startblock

如果指定,则损坏检查从给定块开始,并跳过之前所有块。 如果startblock超出目标表块号范围,则会报错。

默认从第一个块开始检查。

endblock

如果指定,则损坏检查在指定块结束,并跳过后面所有块。 如果endblock超出目标表块号范围,则会报错。

默认会检查所有块。

对于每一处检测到的损坏,verify_heapam都会返回一行, 其中包含下列列:

blkno

包含损坏页面的块号。

offnum

损坏元组的 OffsetNumber。

attnum

如果损坏只针对元组中的某个列而不是整个元组,则表示该损坏列的属性编号。

msg

描述所检测到问题的消息。

F.1.2. 可选的heapallindexed验证 #

当 B-树验证函数的heapallindexed参数为 true时,会针对与目标索引关系相关联的表执行一个额外的验证阶段。 这一阶段由一次CREATE INDEX CONCURRENTLY操作构成, 它会借助一个临时的、位于内存中的汇总结构,检查所有假想的新索引元组是否存在。 这个汇总结构会在基本验证第一阶段中按需构建,并为目标索引中找到的每个元组生成指纹heapallindexed验证背后的总体原则是:一个与现有目标索引等价的新索引, 只能包含那些可以在现有结构中找到的项。

额外的heapallindexed阶段会带来显著开销: 验证通常需要耗费数倍于平常的时间。不过,执行heapallindexed验证时, 所获取的关系级锁并不会发生变化。

这个汇总结构的大小受maintenance_work_mem限制。 为了确保对每个本应在索引中有表示的堆元组而言,漏检一处不一致的概率不超过 2%, 每个元组大约需要 2 字节内存。为每个元组提供的内存越少,漏掉不一致的概率就会缓慢上升。 这种方法显著限制了验证开销,同时只会轻微降低发现问题的概率, 对那些将验证视为例行维护任务的部署环境尤其如此。 每次重新执行验证时,任何单个缺失或格式错误的元组都会再次获得被检测到的机会。

F.1.3. 有效使用amcheck #

amcheck能够有效检测出多种 数据校验和 无法捕捉的故障模式,包括:

  • 由操作符类实现错误导致的结构不一致。

    这也包括因操作系统排序规则的比较规则发生变化而引起的问题。 像text这类可排序类型的数据值之间的比较必须是不可变的 (正如用于 B-树索引扫描的所有比较都必须不可变一样), 这就意味着操作系统排序规则绝不能发生变化。 虽然这种情况比较少见,但操作系统排序规则的更新确实可能导致此类问题。 更常见的是主服务器与后备服务器之间的排序顺序不一致, 这可能是因为两边使用的操作系统版本不同。 这类不一致通常只会出现在后备服务器上,因此通常也只能在后备服务器上检测到。

    如果出现此类问题,它未必会影响每一个按受影响排序规则排序的索引, 因为被索引的值也可能恰好在行为不一致的情况下仍具有相同的绝对顺序。 关于PostgreSQL如何使用操作系统区域设置和排序规则的更多细节, 见Section 23.1Section 23.2

  • 索引与其所索引的堆关系之间的结构不一致 (在执行heapallindexed验证时)。

    在正常运行期间,索引并不会与其堆关系进行交叉核对。 堆损坏的症状可能十分隐蔽。

  • 假设存在的、底层PostgreSQL访问方法代码、 排序代码或事务管理代码中尚未发现的缺陷所导致的损坏。

    对索引结构完整性的自动验证,在对新的或拟议中的 PostgreSQL特性进行一般性测试时具有作用, 因为这些特性完全可能引入逻辑不一致。 对表结构以及相关可见性、事务状态信息的验证,也起着类似作用。 一种显而易见的测试策略,是在运行标准回归测试时持续调用 amcheck函数。 关于如何运行测试,见Section 31.1

  • 在禁用数据校验和时,由文件系统或存储子系统故障造成的损坏。

    请注意,如果访问某个块时只是命中了共享缓冲区, 那么amcheck检查的是验证时该页面在某个共享内存缓冲区中的表示。 因此,amcheck并不一定会检查验证时从文件系统读入的数据。 另请注意,当启用了校验和时,如果某个损坏块被读入缓冲区, amcheck可能会因为校验和失败而引发错误。

  • 由有缺陷的 RAM 或更广义的内存子系统导致的损坏。

    PostgreSQL并不防御可纠正的内存错误, 并且假定所用 RAM 采用业界标准的纠错码(ECC)或更强的保护机制。 然而,ECC 内存通常只对单比特错误有效, 不应被视为能对导致内存损坏的故障提供绝对保护。

    执行heapallindexed验证时, 由于会测试严格的二进制相等性,并且还会检查堆中的被索引属性, 因而检测出单比特错误的机会通常会大大增加。

结构损坏可能是由于存储硬件故障,或者关系文件被无关软件覆盖或修改而产生的。 这类损坏也可以通过数据页校验和检测到。

关系页面即使格式正确、内部一致,并且相对于其自身内部校验和也是正确的, 仍然可能包含逻辑损坏。因此,这类损坏无法通过校验和检测到。 例如,主表中的某个 toasted 值在 TOAST 表中缺少对应条目, 或者主表中的某个元组具有比数据库或集簇中最早的有效事务 ID 更旧的事务 ID。

在生产系统中,已经观察到多种导致逻辑损坏的根本原因, 包括PostgreSQL服务器软件中的缺陷、 设计欠妥的备份恢复工具,以及用户错误。

受损关系在在线生产环境中最令人担忧,而恰恰这些环境最不欢迎高风险活动。 基于这个原因,verify_heapam被设计成能够在不过度增加风险的前提下诊断损坏。 它无法防范所有导致后端崩溃的原因,因为在严重损坏的系统上,甚至执行调用它的查询本身都可能不安全。 该函数会访问系统目录表;如果系统目录自身已损坏,这也可能带来问题。

一般来说,amcheck只能证明损坏存在,无法证明损坏不存在。

F.1.4. 修复损坏 #

amcheck报告的与损坏有关的错误绝不应被当作误报。 amcheck会在那些按定义绝不应该发生的情况下抛出错误, 因此通常需要对这类错误进行仔细分析。

对于amcheck检测到的问题,并不存在通用的修复方法。 应当查明导致不变式遭到破坏的根本原因。 在诊断amcheck检测到的损坏时, pageinspect可能会发挥有用作用。 REINDEX未必能够有效修复损坏。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。