PostgreSQL · 错误码速查
PostgreSQL extension "xxx" is not available:服务端的扩展目录里没有它的 control 文件,先看 DETAIL 里那条路径
ERROR: extension "postgis" is not available,DETAIL: Could not open extension control file ".../extension/postgis.control": No such file or directory.(SQLSTATE 0A000 feature_not_supported)表示运行这个数据库的那套 PostgreSQL 的 SHAREDIR/extension 目录里没有 postgis.control,也就是扩展包没装在这台服务器、这个大版本上。DETAIL 里的路径就是服务端实际查找的位置,照着它装包最准。还有一种情况是扩展已被新版本移除:PG17 起 adminpack、old_snapshot 都会报这句,装包解决不了,只能在升级前删掉。control 在、.so 不在时报的是另一句 could not access file "$libdir/…"(58P01)。
官方原文
extension "%s" is not available出自 PostgreSQL 源码 src/backend/commands/extension.c 的 parse_extension_control_file()(REL_17_STABLE),注释原文为 missing control file indicates extension is not installed;同处的 DETAIL 为 Could not open extension control file "%s": %m.,HINT 为 The extension must first be installed on the system where PostgreSQL is running.,错误码 ERRCODE_FEATURE_NOT_SUPPORTED(0A000)。
出处:PostgreSQL 源码 REL_17_STABLE:src/backend/commands/extension.c(parse_extension_control_file) 最后核对:
| SQLSTATE | 0A000(feature_not_supported,Class 0A) | 出处 |
|---|---|---|
| control 文件位置 | 必须放在服务端安装的 SHAREDIR/extension 目录,文件名为 扩展名.control | 出处 |
| PG17 移除的 contrib | adminpack(发布说明写明);old_snapshot(17 源码 contrib 目录已无,测试库 17.12 报 0A000) | 出处 |
| 版本号不对 | 报 22023 invalid_parameter_value,不是 0A000(测试库实测) | 出处 |
| 测试环境 | 测试库、自造数据,PG 16.16/17.12(apt.postgresql.org 的 Debian 包解包到实验目录,lc_messages=C),非客户环境 | |
| 最后核对 | 2026-11-13 |
盈尺实测(测试库,非官方文档):2026-11-13 在 box 本机 PostgreSQL 17.12 与 16.16 测试库复现 0A000(未装 / PG17 已移除)、22023(版本无脚本或无升级路径)、55000(未预加载),并对照 control 在、.so 不在时的 58P01。 本页第一段:测试库复现输出 →
CREATE EXTENSION 失败的 5 种原文(PG 17.12 / 16.16 测试库实测)
2026-11-13 我在 box 本机两个测试实例上(测试库、自造数据,PG 16.16/17.12(apt.postgresql.org 的 Debian 包解包到实验目录,lc_messages=C),非客户环境)逐条执行 CREATE EXTENSION,VERBOSITY verbose 输出如下,单条 24–50 ms(含建连接):
| 我执行的语句 | 报错原文(节选) | SQLSTATE |
|---|---|---|
| CREATE EXTENSION postgis;(同样试了 timescaledb) | extension "postgis" is not available;DETAIL: Could not open extension control file "…/share/postgresql/17/extension/postgis.control": No such file or directory. | 0A000 |
| CREATE EXTENSION adminpack; / old_snapshot;(PG17) | extension "adminpack" is not available(old_snapshot 同句) | 0A000 |
| CREATE EXTENSION inch_demo;(自造:control 和 SQL 在,.so 不在) | could not access file "$libdir/inch_demo": No such file or directory | 58P01 |
| CREATE EXTENSION pg_trgm VERSION '9.9'; | extension "pg_trgm" has no installation script nor update path for version "9.9" | 22023 |
| 装 1.5 后 ALTER EXTENSION pg_trgm UPDATE TO '9.9'; | extension "pg_trgm" has no update path from version "1.5" to version "9.9" | 22023 |
| 未预加载时 CREATE EXTENSION pg_stat_statements; 再查视图 | CREATE EXTENSION 成功;查询报 pg_stat_statements must be loaded via "shared_preload_libraries" | 55000 |
0A000 的完整三行在 17.12 上是:ERROR: extension "postgis" is not available / DETAIL: Could not open extension control file "…/postgis.control": No such file or directory. / HINT: The extension must first be installed on the system where PostgreSQL is running.。三种报错对应三个不同的修法:0A000 装包或换方案,58P01 补库文件,22023 改版本号,别混在一起查。
DETAIL 里的路径就是答案:包要装到这套 PG 的 SHAREDIR
HINT 那句 on the system where PostgreSQL is running 很关键:扩展包要装在跑数据库服务的那台机器、那个大版本上,装在应用服务器、跳板机或另一个大版本目录里都没用。测试机上系统自带的客户端包指向 /usr/share/postgresql/17,而服务端报错里的路径是实验目录下的 …/postgresql-17/usr/share/postgresql/17/extension/——照命令行去放文件就会放错地方。
SELECT setting FROM pg_config WHERE name = 'SHAREDIR';
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('postgis', 'pg_trgm', 'pg_stat_statements', 'adminpack')
ORDER BY 1;测试库 17.12 上跑同类查询(名单里另加了自造的 inch_demo)返回 inch_demo 1.0、pg_stat_statements 1.11、pg_trgm 1.6 三行,postgis、adminpack 根本不在结果里——不在 pg_available_extensions 里的扩展,CREATE EXTENSION 一定报 0A000。这条查询可以放进升级或建库前的检查清单。
PG17 起 adminpack、old_snapshot 装不上:这不是漏装
PG17 发布说明写明 Remove adminpack contrib extension(它原本服务于已停止维护的 pgAdmin III);old_snapshot 依赖的 old_snapshot_threshold 参数也在 17 被移除,17 源码的 contrib 目录里已经没有 old_snapshot。测试库 17.12 上两者都报 0A000,没有「17 版包」可装。
影响在升级:我在 16.16 旧库 shop 装了这两个扩展,pg_upgrade 到 17.12 的 --check 在 Checking for presence of required libraries 一步 fatal,loadable_libraries.txt 里正是 $libdir/adminpack 和 $libdir/old_snapshot(详见 58P01 页的 pg_upgrade 一节)。在旧集群 DROP EXTENSION adminpack; DROP EXTENSION old_snapshot;(33 ms)后,这两条就从清单里消失了。
我的判断:升级到 17 之前先查 SELECT extname FROM pg_extension WHERE extname IN ('adminpack','old_snapshot');,有就先确认还有没有人在用、删掉——这比 initdb 完新集群再看 --check 报错早一步。
版本号写错报 22023:先查有哪些版本可走
迁移脚本里写死 CREATE EXTENSION x VERSION '…' 或 ALTER EXTENSION x UPDATE TO '…',目标版本在这台服务端上没有安装脚本或升级路径时,报的是 22023 而不是 0A000(原文见上表)。可走的版本用只读视图查:
SELECT name, version, installed
FROM pg_available_extension_versions
WHERE name = 'pg_trgm'
ORDER BY version;测试库 17.12 输出 pg_trgm 1.3、1.4、1.5、1.6 四行,当时装的是 1.6(installed = t)。脚本里最好不写死版本,或者写之前对着这张表核对。
CREATE EXTENSION 成功也不等于能用:pg_stat_statements 的 55000
测试库里我先 ALTER SYSTEM RESET shared_preload_libraries 并重启,再 CREATE EXTENSION pg_stat_statements:建扩展成功,一查视图就报 55000: pg_stat_statements must be loaded via "shared_preload_libraries"。官方文档原话是 The module must be loaded by adding pg_stat_statements to shared_preload_libraries in postgresql.conf,加或去掉都要重启。
设回 shared_preload_libraries = 'pg_stat_statements' 并重启后,SELECT count(*) > 0 FROM pg_stat_statements 返回 t。注意拼写:少一个 s 的 pg_stat_statement 会让服务启动失败(FATAL could not access file,见 58P01 页)。
处理顺序
- 读 DETAIL 里的 control 文件路径,确认它属于正在运行的服务端(
SELECT setting FROM pg_config WHERE name='SHAREDIR')。 - 查
pg_available_extensions:不在列表里 → 用操作系统包管理器装与服务端大版本一致的扩展包(包名因发行版而异),装完重新 CREATE EXTENSION,一般不需要重启;需要预加载的扩展另配 shared_preload_libraries 并重启。 - 扩展已被新版本移除(如 PG17 的 adminpack、old_snapshot)→ 不再装,升级前在旧库 DROP,并找替代方案。
- 报 22023 → 改版本号,对照
pg_available_extension_versions。 - control 在、.so 不在(58P01)→ 转到 could not access file "$libdir/…" 页。
未测:真实 PostGIS / TimescaleDB 包的安装过程与包名、Windows 和 RPM 的目录布局、Docker 官方镜像里装扩展、托管云数据库(通常只能装白名单内扩展)。本页的报错原文都来自自造环境下的未安装状态。
常见问题
extension "postgis" is not available 是什么意思?
SQLSTATE 0A000:运行这个数据库的 PostgreSQL 的 SHAREDIR/extension 目录里没有 postgis.control,也就是扩展包没装在这台服务器的这个大版本上。按 DETAIL 里的路径装对应版本的包。
could not open extension control file 和 could not access file "$libdir/…" 有什么区别?
前者(0A000)是 control 文件不在,扩展整个没装;后者(58P01)是 control 在、C 库文件 .so 不在,常见于包装了一半或升级后只装了部分文件。
PostgreSQL 17 为什么装不了 adminpack?
adminpack 在 PG17 被移除(发布说明写明),old_snapshot 也已不在 17 的 contrib 中。没有 17 版可装,升级前在旧集群 DROP EXTENSION,否则 pg_upgrade --check 会报缺库。
CREATE EXTENSION pg_stat_statements 成功了,查询却报错?
pg_stat_statements 必须写进 shared_preload_libraries 并重启。测试库未预加载时 CREATE EXTENSION 成功,但查视图报 55000。
has no installation script nor update path for version 怎么办?
这是 22023:指定的版本在当前服务端上没有安装脚本或升级路径。用 pg_available_extension_versions 查可用版本,改脚本里的版本号或不写死版本。
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-11-13)
- PostgreSQL 源码 REL_17_STABLE:src/backend/commands/extension.c(parse_extension_control_file)
- PostgreSQL 17 文档 36.17:Packaging Related Objects into an Extension(Extension Files)
- PostgreSQL 17 文档:CREATE EXTENSION
- PostgreSQL 17 文档:pg_available_extensions 视图
- PostgreSQL 17 Release Notes(Remove adminpack contrib extension;Remove old_snapshot_threshold)
- PostgreSQL 源码 REL_17_STABLE:contrib/Makefile(已无 adminpack、old_snapshot)
- PostgreSQL 17 文档 F.30:pg_stat_statements
- PostgreSQL 17 文档:Appendix A. PostgreSQL Error Codes
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。除标明「盈尺实测」的一段外,其余内容都来自官方文档。