如何查看扩展
-
当前实例支持的扩展:pg_available_extensions列出可用扩展(在安装包里有.control文件的扩展),这是服务器级别的。 -
当前数据库里已安装的扩展:pg_extension或者 \dx。
注意,如果需要扩展可用,但每个数据库都需要自己安装才能使用。
pg_available_extensions
从 pg_available_extensions 中看到的扩展信息实际上来源于 share/extension/,share/extension/ 是 PostgreSQL 安装目录下的一个子目录,用于存放扩展的控制文件(.control)和 SQL 安装脚本。如果用源码编译安装, share/extension/的路径是在 /usr/local/pgsql/share/extension/。
$ ll /usr/local/pgsql/share/extension total 76 -rw-r--r-- 1 root root 13208 Jun 15 08:26 pg_repack--1.5.2.sql -rw-r--r-- 1 root root 179 Jun 15 08:26 pg_repack.control
...
-rw-r--r-- 1 root root 2114 Jul 6 09:00 pg_stat_statements--1.9--1.10.sql -rw-r--r-- 1 root root 205 Jul 6 09:00 pg_stat_statements.control -rw-r--r-- 1 root root 658 May 13 2025 plpgsql--1.0.sql -rw-r--r-- 1 root root 193 May 13 2025 plpgsql.control
里面有两类文件:
-
.control文件:定义扩展名称、版本等信息 -
--<版本>.sql文件:安装或升级扩展的 SQL 脚本
Datum pg_available_extensions(PG_FUNCTION_ARGS) {ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;char *location;DIR *dir;struct dirent *de;/* Build tuplestore to hold the result rows */InitMaterializedSRF(fcinfo, 0);location = get_extension_control_directory();dir = AllocateDir(location);/** If the control directory doesn't exist, we want to silently return an* empty set. Any other error will be reported by ReadDir.*/if (dir == NULL && errno == ENOENT){/* do nothing */}else{while ((de = ReadDir(dir, location)) != NULL){ExtensionControlFile *control;char *extname;Datum values[3];bool nulls[3];if (!is_extension_control_filename(de->d_name))continue;/* extract extension name from 'name.control' filename */extname = pstrdup(de->d_name);*strrchr(extname, '.') = '\0';/* ignore it if it's an auxiliary control file */if (strstr(extname, "--"))continue;control = read_extension_control_file(extname);memset(values, 0, sizeof(values));memset(nulls, 0, sizeof(nulls));/* name */values[0] = DirectFunctionCall1(namein,CStringGetDatum(control->name));/* default_version */if (control->default_version == NULL)nulls[1] = true;elsevalues[1] = CStringGetTextDatum(control->default_version);/* comment */if (control->comment == NULL)nulls[2] = true;elsevalues[2] = CStringGetTextDatum(control->comment);tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,values, nulls);}FreeDir(dir);}return (Datum) 0; }
上述代码是 PostgreSQL 内部实现 pg_available_extensions() 的 C 语言函数。它的作用是扫描 share/extension/目录并返回可用的扩展信息。
如果删除了share/extension/目录下对应扩展的.control 文件 和 .sql 文件,则再次查询 pg_available_extensions 就看不到对应的扩展信息。
如何安装 pg_stat_statements
1. 查看插件是否存在
SELECT * FROM pg_available_extensions WHERE name='pg_stat_statements';
2. 不存在的话
进入 PostgreSQL 源码目录
cd contrib/pg_stat_statements make make install
3. 在数据库中创建扩展
\c your_database_name CREATE EXTENSION pg_stat_statements; \dx
此时,如果直接查询 pg_stat_statements 的话,会提示:
ERROR: pg_stat_statements must be loaded via shared_preload_librarie
4. 设置 shared_preload_libraries
确保在 postgresql.conf 中启用了统计:
shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.track = all pg_stat_statements.max = 10000 # 可按需调整 pg_stat_statements.track_utility = on # 可选,统计 utility 命令
注意,修改 shared_preload_libraries 需要 重启 PostgreSQL 才生效。
5. 重启实例。
$ pg_ctl restart -D /data/pgsql/5432/data/
6. 查询 pg_stat_statements。
SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;
pg_stat_statements 文档:https://www.postgresql.org/docs/current/pgstatstatements.html#PGSTATSTATEMENTS-PG-STAT-STATEMENTS-INFO
如何删除 pg_stat_statements
1. 不卸载扩展,只把统计数据清零:
SELECT pg_stat_statements_reset();
2. 卸载删除 pg_stat_statements 扩展
DROP EXTENSION pg_stat_statements;
注意
- 只能在当前数据库卸载
- 若其他数据库也安装了,需要逐库 drop
卸载前必须确认 shared_preload_libraries 不再包含 pg_stat_statements
编辑 postgresql.conf 注释掉:
shared_preload_libraries = 'pg_stat_statements'
然后重启 PostgreSQL。
3. 删除扩展的文件(极少需要)
如果你想 彻底删除扩展文件(一般不建议):
路径通常在:$PGHOME/share/extension/
删除:
pg_stat_statements.control
pg_stat_statements--*.sql
再从 lib 目录删除 .so:
$PGHOME/lib/pg_stat_statements.so
这通常用于自定义编译或安装冲突排查,不建议在生产环境手动删文件。