一、功能概述
1.1 功能简介
云数据库 PostgreSQL 租户自定义扩展功能允许用户在不登录数据库服务器、不上传 control、SQL 或 SO 文件、也不获得 PostgreSQL
superuser 权限的前提下,通过 SQL 注册、创建、升级和卸载自己的数据库扩展。该功能底层基于 pg_tle。腾讯云负责预装和维护基础组件,用户负责定义扩展名称、版本、安装 SQL、升级 SQL 和依赖关系。扩展注册完成后,仍然使用 PostgreSQL 标准命令管理生命周期:
CREATE EXTENSION extension_name;ALTER EXTENSION extension_name UPDATE;DROP EXTENSION extension_name;
1.2 支持版本
v17.11_r1.25、v18.6_r1.15及以上版本。
1.3 使用限制
使用前必须将
pg_tle 配置到 shared_preload_libraries 并重启实例,否则不能在数据库中创建基础扩展。参数设置方法可参考 设置实例参数。预加载配置对整个实例生效,但
CREATE EXTENSION pg_tle、租户扩展定义和安装状态按数据库保存;需要在哪个数据库使用,就应在哪个数据库中创建和注册。pgtle_admin 是专用特权管理角色,仅应授予可信的扩展管理账号。它不是 PostgreSQL superuser。租户自定义扩展不提供 control、SQL 文件或自定义 SO 动态库的上传和部署通道。
扩展安装和升级脚本以执行相关命令的用户权限运行,不能绕过 PostgreSQL 的数据库、Schema、对象和过程语言权限。
普通扩展脚本主要面向 SQL 和腾讯云产品支持的过程语言。实际可用语言以目标实例提供的语言及产品允许范围为准。
自定义基础类型是以
bytea 为内部载体的受限类型,输入输出函数必须使用 trusted 语言,并满足固定签名、STRICT、IMMUTABLE 等要求。安装和升级脚本不能包含
BEGIN、COMMIT 等事务控制语句;其整体事务由 PostgreSQL 扩展框架管理。当前不开放底层 hook 扩展能力。
该功能适合 SQL 和受支持过程语言实现的业务扩展,不能替代依赖本地代码、服务器文件、操作系统库或 PostgreSQL 内核修改的传统插件。
1.4 功能概览
功能 | 使用方式 | 说明 |
注册初始版本 | `pgtle.install_extension(...)` | 注册扩展控制信息、初始版本安装 SQL、依赖和安装 Schema |
创建扩展 | `CREATE EXTENSION` | 使用 PostgreSQL 标准命令创建已注册扩展 |
注册完整版本 | `pgtle.install_extension_version_sql(...)` | 为指定版本注册可独立安装的完整 SQL |
注册升级路径 | `pgtle.install_update_path(...)` | 定义旧版本到新版本的增量升级脚本 |
设置默认版本 | `pgtle.set_default_version(...)` | 设置未显式指定版本时使用的默认版本 |
升级扩展 | `ALTER EXTENSION ... UPDATE` | 使用 PostgreSQL 标准命令执行已注册升级路径 |
查询扩展 | `pgtle.available_extensions()` | 查询扩展名称、默认版本、依赖和安装 Schema 等信息 |
查询版本 | `pgtle.available_extension_versions()` | 查询已注册的全部版本 |
查询升级路径 | `pgtle.extension_update_paths(...)` | 查询版本之间的可用升级路径 |
删除扩展实例 | `DROP EXTENSION` | 删除当前数据库中已经创建的扩展对象 |
删除扩展定义 | `pgtle.uninstall_extension(...)` | 删除数据库内注册的控制信息、版本 SQL 和升级路径 |
创建基础类型 | `pgtle.create_shell_type(...)`、`pgtle.create_base_type(...)` | 使用受支持的可信语言构建受限自定义基础类型 |
1.5 作用范围
租户自定义扩展的定义和安装状态按数据库管理:
在数据库 A 注册的扩展不会自动出现在数据库 B。
不同数据库可以注册和安装不同扩展。
不同数据库可以使用不同扩展版本。
扩展对象继续受到数据库、Schema、对象所有权和执行权限控制。
需要注意:
shared_preload_libraries 是实例级参数。pgtle_admin 是实例内的集群级角色。CREATE EXTENSION pg_tle、扩展定义和扩展安装状态属于数据库级对象。二、使用前提
2.1 实例版本支持该功能
连接目标数据库后,可以执行以下 SQL 检查服务器是否提供
pg_tle:SELECT name, default_version, installed_versionFROM pg_catalog.pg_available_extensionsWHERE name = 'pg_tle';
预期返回一条记录。如果没有返回记录,说明当前实例版本尚未提供该功能。
本文完整示例使用以下函数签名:
pgtle.install_extension(text, text, text, text, text[], text)
该签名要求 pg_tle 版本不低于1.5.0。可以执行以下 SQL 检查:
SELECT pg_catalog.to_regprocedure('pgtle.install_extension(text,text,text,text,text[],text)') IS NOT NULL AS supported;
预期结果为
t。2.2 配置预加载参数
在 云数据库 PostgreSQL 控制台 的实例参数设置中,确认
shared_preload_libraries 包含 pg_tle。如果需要新增该值,请按照控制台提示保存参数,并重启实例使配置生效。数据库重启后执行:
SHOW shared_preload_libraries;
返回值中应包含
pg_tle。说明:
修改
shared_preload_libraries 通常需要重启实例。请在业务允许的维护窗口内操作。2.3 准备管理账号
建议使用两个角色:
角色 | 用途 | 建议权限 |
实例管理账号 | 创建基础扩展、管理角色授权 | `tencentdb_superuser` 或产品允许的等效管理权限 |
扩展管理账号 | 注册扩展定义、版本和升级路径 | `pgtle_admin` 成员,并拥有目标数据库和 Schema 所需权限 |
pgtle_admin 是专用受控管理角色,不是 PostgreSQL superuser。应按照最小授权原则,只授予可信的扩展管理账号。2.4 在目标数据库启用基础扩展
使用具备扩展创建权限的管理账号连接目标数据库,执行:
CREATE EXTENSION IF NOT EXISTS pg_tle;
确认安装结果:
SELECT extname, extversionFROM pg_catalog.pg_extensionWHERE extname = 'pg_tle';
预期返回一条
pg_tle 记录。如果需要在多个数据库中使用租户自定义扩展功能,应在每个目标数据库中分别执行
CREATE EXTENSION pg_tle。2.5 授予扩展管理权限
由具备角色管理权限的账号执行:
GRANT pgtle_admin TO extension_admin;
其中,
extension_admin 替换为实际扩展管理账号。如果希望把权限授予当前登录账号,可以执行:
DO $grant_pgtle_admin$DECLAREtarget_role name := CURRENT_USER;BEGINEXECUTE pg_catalog.format('GRANT pgtle_admin TO %I',target_role);END$grant_pgtle_admin$;
检查当前账号是否已获得显式授权:
SELECT EXISTS (SELECT 1FROM pg_catalog.pg_auth_members AS amJOIN pg_catalog.pg_roles AS granted_roleON granted_role.oid = am.roleidJOIN pg_catalog.pg_roles AS member_roleON member_role.oid = am.memberWHERE granted_role.rolname = 'pgtle_admin'AND member_role.rolname = CURRENT_USER) AS explicit_pgtle_admin_membership;
预期结果为
t。三、快速入门
本章创建一个名为
tle_distance_demo 的距离计算扩展。扩展 0.1 版本包含三个函数:通用距离函数、曼哈顿距离函数和欧氏距离函数。执行以下步骤前,请确保:
已完成第二章中的配置和授权。
当前账号是
pgtle_admin 成员。当前账号对目标数据库具有
CREATE 权限。数据库中不存在业务正在使用的同名扩展或 Schema。
3.1 清理可能存在的演示对象
如果是第一次执行,本步骤只会返回对象不存在的提示;如果需要重复运行示例,本步骤可以清理上一次执行留下的对象。
DROP EXTENSION IF EXISTS tle_distance_demo;SELECT pgtle.uninstall_extension_if_exists('tle_distance_demo');DROP SCHEMA IF EXISTS tle_distance_demo CASCADE;
3.2 注册扩展0.1
复制并执行以下完整 SQL:
SELECT pgtle.install_extension('tle_distance_demo','0.1','Distance functions for two points',$install_0_1$CREATE FUNCTION tle_distance_demo.distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision,norm integer)RETURNS double precisionLANGUAGE sqlAS $function$SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::double precision / norm);$function$;CREATE FUNCTION tle_distance_demo.manhattan_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 1);$function$;CREATE FUNCTION tle_distance_demo.euclidean_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 2);$function$;$install_0_1$,NULL::text[],'tle_distance_demo');
参数说明:
参数 | 示例值 | 说明 |
`name` | `tle_distance_demo` | 扩展名称,也是后续 `CREATE EXTENSION` 使用的名称 |
`version` | `0.1` | 初始版本 |
`description` | `Distance functions for two points` | 扩展说明 |
`ext` | `$install_0_1$...$install_0_1$` | 扩展安装 SQL |
`requires` | `NULL::text[]` | 额外依赖扩展,本例无额外依赖 |
`schema` | `tle_distance_demo` | 固定安装 Schema |
执行成功返回:
t
此时只是注册了扩展定义,尚未创建距离计算函数。
3.3 查询已注册扩展
查询扩展控制信息:
SELECTname,default_version,schema,requires,commentFROM pgtle.available_extensions()WHERE name = 'tle_distance_demo';
关键结果应为:
name = tle_distance_demodefault_version = 0.1schema = tle_distance_demorequires = {pg_tle}
pg_tle 会自动加入依赖列表,无需手动声明。查询可用版本:
SELECTname,version,schema,requires,commentFROM pgtle.available_extension_versions()WHERE name = 'tle_distance_demo'ORDER BY version;
此时只会看到版本
0.1。3.4 创建扩展
执行 PostgreSQL 标准命令:
CREATE EXTENSION tle_distance_demo VERSION '0.1';
扩展控制信息指定了 Schema
tle_distance_demo。当 Schema 不存在时,安装流程会创建该 Schema,然后执行注册的安装 SQL。确认安装结果:
SELECT extname, extversionFROM pg_catalog.pg_extensionWHERE extname = 'tle_distance_demo';
预期结果:
tle_distance_demo | 0.1
3.5 调用扩展函数
计算点
(1, 1) 到点 (5, 5) 的曼哈顿距离:SELECT tle_distance_demo.manhattan_distance(1, 1, 5, 5);
预期返回:
8
计算两点之间的欧氏距离:
SELECT round(tle_distance_demo.euclidean_distance(1, 1, 5, 5)::numeric,6);
预期返回:
5.656854
四、扩展版本管理
4.1 注册升级路径
下面将扩展从
0.1 升级到 0.2。业务计算逻辑不变,但为函数增加 IMMUTABLE 和 PARALLEL SAFE 属性。复制并执行以下 SQL:
SELECT pgtle.install_update_path('tle_distance_demo','0.1','0.2',$update_0_1_to_0_2$CREATE OR REPLACE FUNCTION tle_distance_demo.distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision,norm integer)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::double precision / norm);$function$;CREATE OR REPLACE FUNCTION tle_distance_demo.manhattan_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 1);$function$;CREATE OR REPLACE FUNCTION tle_distance_demo.euclidean_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 2);$function$;$update_0_1_to_0_2$);
成功时返回
t。4.2 查询升级路径
SELECT source, target, pathFROM pgtle.extension_update_paths('tle_distance_demo')ORDER BY source, target;
结果中应包含:
0.1 | 0.2 | 0.1--0.2
4.3 设置默认版本
SELECT pgtle.set_default_version('tle_distance_demo','0.2');
成功时返回
t。查询默认版本:
SELECT name, default_versionFROM pgtle.available_extensions()WHERE name = 'tle_distance_demo';
预期
default_version 为 0.2。4.4 升级扩展
执行 PostgreSQL 标准命令:
ALTER EXTENSION tle_distance_demo UPDATE;
也可以显式指定目标版本:
ALTER EXTENSION tle_distance_demo UPDATE TO '0.2';
确认当前安装版本:
SELECT extname, extversionFROM pg_catalog.pg_extensionWHERE extname = 'tle_distance_demo';
预期结果:
tle_distance_demo | 0.2
4.5 验证升级结果
SELECT tle_distance_demo.manhattan_distance(1, 1, 5, 5) AS manhattan,round(tle_distance_demo.euclidean_distance(1, 1, 5, 5)::numeric,6) AS euclidean;
预期结果:
manhattan = 8euclidean = 5.656854
业务行为保持不变,扩展版本已升级到
0.2。4.6 注册独立版本安装脚本
如果希望新数据库能够不经过
0.1,直接创建 0.2,可以为 0.2 注册完整安装脚本:SELECT pgtle.install_extension_version_sql('tle_distance_demo','0.2',$install_0_2$CREATE FUNCTION tle_distance_demo.distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision,norm integer)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::double precision / norm);$function$;CREATE FUNCTION tle_distance_demo.manhattan_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 1);$function$;CREATE FUNCTION tle_distance_demo.euclidean_distance(x1 double precision,y1 double precision,x2 double precision,y2 double precision)RETURNS double precisionLANGUAGE sqlIMMUTABLEPARALLEL SAFEAS $function$SELECT tle_distance_demo.distance(x1, y1, x2, y2, 2);$function$;$install_0_2$);
说明:
如果已通过其他操作注册了同名
0.2 完整安装脚本,请勿重复执行。升级路径和完整版本脚本用途不同:升级路径描述“如何从旧版本变到新版本”,完整版本脚本描述“如何直接安装某个版本”。五、查询扩展信息
5.1 查询所有已注册扩展
SELECT *FROM pgtle.available_extensions()ORDER BY name;
5.2 查询扩展所有版本
SELECT *FROM pgtle.available_extension_versions()WHERE name = 'tle_distance_demo'ORDER BY version;
5.3 查询升级路径
SELECT source, target, pathFROM pgtle.extension_update_paths('tle_distance_demo')ORDER BY source, target;
5.4 查询已经创建的扩展
SELECT extname, extversionFROM pg_catalog.pg_extensionORDER BY extname;
5.5 查询扩展对象
SELECTe.extname,object_info.type AS object_type,object_info.schema AS schema_name,object_info.name AS object_name,object_info.identity AS object_identityFROM pg_catalog.pg_extension AS eJOIN pg_catalog.pg_depend AS dON d.refclassid = 'pg_catalog.pg_extension'::regclassAND d.refobjid = e.oidAND d.deptype = 'e'CROSS JOIN LATERAL pg_catalog.pg_identify_object(d.classid,d.objid,d.objsubid) AS object_infoWHERE e.extname = 'tle_distance_demo'ORDER BYobject_info.type,object_info.schema,object_info.name,object_info.identity;
函数等非
pg_class 对象不会出现在上述结果中。可以单独查询扩展 Schema 下的函数:SELECTn.nspname AS schema_name,p.proname AS function_name,pg_catalog.pg_get_function_identity_arguments(p.oid) AS argumentsFROM pg_catalog.pg_proc AS pJOIN pg_catalog.pg_namespace AS nON n.oid = p.pronamespaceWHERE n.nspname = 'tle_distance_demo'ORDER BY function_name, arguments;
六、卸载扩展
6.1 删除扩展实例
先删除当前数据库中已经创建的扩展对象:
DROP EXTENSION tle_distance_demo;
如果其他对象依赖该扩展,PostgreSQL 会拒绝删除。请先处理依赖关系,不建议在不了解影响范围时直接使用
CASCADE。6.2 删除扩展注册信息
扩展实例删除后,再删除注册的控制信息、版本脚本和升级路径:
SELECT pgtle.uninstall_extension('tle_distance_demo');
成功时返回
t。正确顺序是:
1.
DROP EXTENSION 删除已经安装的扩展实例。2.
pgtle.uninstall_extension 删除数据库内的扩展定义。pgtle.uninstall_extension 不会代替 DROP EXTENSION 删除正在使用的扩展实例。6.3 清理残留 Schema
DROP SCHEMA IF EXISTS tle_distance_demo;
6.4 确认清理结果
SELECT NOT EXISTS (SELECT 1FROM pgtle.available_extensions()WHERE name = 'tle_distance_demo') AS extension_registration_removed;
预期返回
t。七、进阶使用:创建自定义基础类型
本章创建一个名为
cloud_email 的自定义类型。该类型在数据写入时检查邮箱格式,并统一转换为小写后保存。自定义基础类型具有以下限制:
内部数据使用
bytea 表示。输入函数签名必须为
text -> bytea。输出函数签名必须为
bytea -> text。输入输出函数必须为
STRICT、IMMUTABLE。输入输出函数必须使用 PostgreSQL 标记为 trusted 的过程语言。
调用账号必须是
pgtle_admin 成员。调用账号必须拥有目标 Schema、shell type 和输入输出函数。
7.1 创建独立 Schema
DROP SCHEMA IF EXISTS tle_type_demo CASCADE;CREATE SCHEMA tle_type_demo;
7.2 创建 shell type
SELECT pgtle.create_shell_type('tle_type_demo','cloud_email');
成功时返回
t。7.3 创建输入函数
CREATE FUNCTION tle_type_demo.cloud_email_in(input text)RETURNS byteaLANGUAGE plpgsqlIMMUTABLESTRICTAS $function$BEGINIF input !~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[.][A-Za-z]{2,}$' THENRAISE EXCEPTION 'invalid email address: "%"', inputUSING ERRCODE = '22023';END IF;RETURN pg_catalog.convert_to(pg_catalog.lower(input), 'UTF8');END$function$;
7.4 创建输出函数
CREATE FUNCTION tle_type_demo.cloud_email_out(input bytea)RETURNS textLANGUAGE sqlIMMUTABLESTRICTAS $function$SELECT pg_catalog.convert_from(input, 'UTF8');$function$;
7.5 完成基础类型定义
cloud_email 是变长类型,因此内部长度使用 -1;存储策略使用 extended:SELECT pgtle.create_base_type('tle_type_demo','cloud_email','tle_type_demo.cloud_email_in(text)'::regprocedure,'tle_type_demo.cloud_email_out(bytea)'::regprocedure,-1,'int4','extended');
成功时返回
t。7.6 创建表并写入数据
CREATE TABLE tle_type_demo.contacts (id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,email tle_type_demo.cloud_email NOT NULL);INSERT INTO tle_type_demo.contacts(email)VALUES('Alice.Example@Example.COM'),('bob@example.com');
查询数据:
SELECT id, email::textFROM tle_type_demo.contactsORDER BY id;
预期结果:
1 | alice.example@example.com2 | bob@example.com
7.7 验证非法值
INSERT INTO tle_type_demo.contacts(email)VALUES ('not-an-email');
预期报错:
ERROR: invalid email address: "not-an-email"
7.8 清理示例
DROP TABLE tle_type_demo.contacts;DROP TYPE tle_type_demo.cloud_email CASCADE;DROP FUNCTION IF EXISTS tle_type_demo.cloud_email_in(text);DROP FUNCTION IF EXISTS tle_type_demo.cloud_email_out(bytea);DROP SCHEMA tle_type_demo;
八、权限与安全说明
8.1 专用管理角色
pgtle_admin 用于执行扩展注册、版本管理、卸载注册信息和基础类型 API。它不是 PostgreSQL superuser,但应被视为特权管理角色。建议:
只授予少量可信账号。
将扩展管理者与普通使用者分离。
定期检查角色成员。
生产发布前审查安装 SQL 和升级 SQL。
不在扩展脚本中加入与业务功能无关的操作。
查询
pgtle_admin 成员:SELECT member_role.rolname AS member_nameFROM pg_catalog.pg_auth_members AS amJOIN pg_catalog.pg_roles AS granted_roleON granted_role.oid = am.roleidJOIN pg_catalog.pg_roles AS member_roleON member_role.oid = am.memberWHERE granted_role.rolname = 'pgtle_admin'ORDER BY member_name;
撤销角色:
REVOKE pgtle_admin FROM extension_admin;
8.2 PostgreSQL 原生权限仍然有效
扩展脚本以执行
CREATE EXTENSION 的用户权限运行。用户能否创建 Schema、函数、表、类型或其他对象,继续由 PostgreSQL 原生权限决定。注册扩展定义与创建扩展实例是两个不同阶段:
注册定义通常需要
pgtle_admin。创建已注册扩展的用户需要目标数据库和 Schema 所要求的权限。
使用扩展对象的用户需要对应对象的访问或执行权限。
8.3 不支持上传自定义 SO
租户自定义扩展功能不提供自定义共享库上传和部署通道。不能通过该功能把新的本地二进制代码写入数据库服务器。
8.4 过程语言限制
普通扩展脚本能否创建某种过程语言函数,取决于:
该过程语言是否由腾讯云数据库 PostgreSQL 提供。
当前用户是否具有语言
USAGE 权限。当前用户是否拥有创建相应函数的权限。
产品是否允许在租户自定义扩展中使用该语言。
自定义基础类型的输入输出函数要求使用 PostgreSQL 标记为 trusted 的过程语言。
8.5 事务与回滚
扩展安装和升级脚本在 PostgreSQL 事务中执行。脚本执行失败时,本次数据库变更可以回滚。
生产发布前仍需验证:
安装脚本能否在空数据库中执行。
升级脚本能否从每个受支持旧版本执行。
升级失败后业务是否可以继续使用旧版本。
扩展对象是否存在未声明依赖。
DROP EXTENSION 是否会影响其他业务对象。九、API 速查
API | 用途 | 主要权限 |
`pgtle.install_extension(...)` | 注册扩展控制信息和初始版本安装脚本 | `pgtle_admin` |
`pgtle.install_extension_version_sql(...)` | 注册某个版本的完整安装脚本 | `pgtle_admin` |
`pgtle.install_update_path(...)` | 注册版本升级路径 | `pgtle_admin` |
`pgtle.set_default_version(...)` | 设置默认版本 | `pgtle_admin` |
`pgtle.available_extensions()` | 查询已注册扩展 | 普通查询权限 |
`pgtle.available_extension_versions()` | 查询所有可用版本 | 普通查询权限 |
`pgtle.extension_update_paths(name)` | 查询升级路径 | 普通查询权限 |
`pgtle.uninstall_extension(name)` | 删除扩展所有注册信息 | `pgtle_admin` |
`pgtle.uninstall_extension(name, version)` | 删除指定版本安装脚本 | `pgtle_admin` |
`pgtle.uninstall_extension_if_exists(name)` | 扩展存在时删除注册信息 | `pgtle_admin` |
`pgtle.uninstall_update_path(...)` | 删除指定升级路径 | `pgtle_admin` |
`pgtle.create_shell_type(...)` | 创建 shell type | `pgtle_admin` 及目标对象权限 |
`pgtle.create_base_type(...)` | 完成基础类型定义 | `pgtle_admin` 及目标对象权限 |
`pgtle.create_operator_func(...)` | 为基础类型创建操作符包装函数 | `pgtle_admin` 及目标对象权限 |
说明:
API 签名可能随 pg_tle 版本变化,请以实例中
\\df pgtle.* 的查询结果为准。查询全部 pgtle 函数:
SELECTn.nspname AS schema_name,p.proname AS function_name,pg_catalog.pg_get_function_identity_arguments(p.oid) AS arguments,pg_catalog.pg_get_function_result(p.oid) AS result_typeFROM pg_catalog.pg_proc AS pJOIN pg_catalog.pg_namespace AS nON n.oid = p.pronamespaceWHERE n.nspname = 'pgtle'ORDER BY function_name, arguments;
十、常见问题
10.1 创建基础扩展时报必须预加载
错误示例:
pg_tle must be loaded via shared_preload_libraries
处理方法:
1. 在控制台参数设置中将
pg_tle 加入 shared_preload_libraries。2. 保存参数。
3. 按照控制台提示重启实例。
4. 重新执行
CREATE EXTENSION pg_tle。10.2 查询不到 pg_tle
如果以下 SQL 没有返回记录:
SELECT *FROM pg_catalog.pg_available_extensionsWHERE name = 'pg_tle';
10.3 执行管理函数提示权限不足
错误通常表现为不能执行
pgtle.install_extension 或其他管理函数。检查当前用户是否为
pgtle_admin 成员:SELECT pg_catalog.pg_has_role(CURRENT_USER,'pgtle_admin','MEMBER');
如果结果为
f,请由具备角色管理权限的账号执行:GRANT pgtle_admin TO extension_admin;
10.4 CREATE EXTENSION 提示权限不足
检查以下权限:
当前用户是否具有目标数据库的
CREATE 权限。当前用户是否可以创建或使用目标 Schema。
安装 SQL 创建的对象是否需要额外权限。
依赖扩展是否已经安装。
对象是否与数据库中已有对象重名。
数据库管理员可以授予数据库创建权限:
GRANT CREATE ON DATABASE current_database_name TO extension_user;
请将
current_database_name 和 extension_user 替换为实际名称。10.5 升级时提示找不到升级路径
执行以下 SQL 查询已注册升级路径:
SELECT source, target, pathFROM pgtle.extension_update_paths('tle_distance_demo')ORDER BY source, target;
如果目标路径不存在,请先通过
pgtle.install_update_path 注册升级脚本。10.6 删除注册信息后扩展对象仍然存在
pgtle.uninstall_extension 删除的是扩展定义,不会代替 DROP EXTENSION 删除已经安装的扩展实例。请按照以下顺序执行:
DROP EXTENSION extension_name;SELECT pgtle.uninstall_extension('extension_name');
10.7 不同数据库查询结果不一致
这是正常现象。租户自定义扩展的定义和安装状态按数据库保存。如果需要在另一个数据库中使用同一扩展,应:
1. 在目标数据库执行
CREATE EXTENSION pg_tle。2. 在目标数据库重新注册扩展定义和版本脚本。
3. 在目标数据库执行
CREATE EXTENSION extension_name。10.8 自定义基础类型创建失败
检查输入输出函数是否满足全部要求:
输入函数参数为
text,返回 bytea。输出函数参数为
bytea,返回 text。两个函数与类型位于同一 Schema。
两个函数均声明为
STRICT、IMMUTABLE。两个函数使用 trusted 过程语言。
当前用户拥有函数和 shell type。
当前用户是
pgtle_admin 成员。当前用户对目标 Schema 有
CREATE 权限。十一、使用建议
11.1 发布前验证
建议在测试数据库完成以下验证后再发布到生产数据库:
1. 从空数据库安装扩展。
2. 调用扩展所有主要函数。
3. 从每个受支持旧版本升级。
4. 模拟升级脚本执行失败并确认事务回滚。
5. 检查扩展对象权限。
6. 检查
DROP EXTENSION 的依赖影响。7. 检查备份恢复和主备切换后的扩展可用性。
11.2 命名建议
扩展名称使用小写字母、数字和下划线。
避免与 PostgreSQL 内置扩展同名。
为扩展使用独立 Schema。
函数和类型使用 Schema 限定名。
版本号使用稳定、可比较的格式,如
1.0、1.1、2.0。安装脚本和升级脚本中避免依赖不确定的
search_path。11.3 权限建议
只向可信账号授予
pgtle_admin。普通业务账号仅授予扩展对象所需的
USAGE、EXECUTE、SELECT 等权限。不使用扩展脚本修改无关角色或对象。
不在扩展脚本中保存密码、密钥或其他敏感信息。
定期审计扩展版本、注册信息和角色成员。
11.4 升级建议
每个生产版本都保留完整安装脚本。
为相邻版本提供明确升级路径。
升级脚本尽量使用可重复验证的 DDL。
不在升级脚本中执行事务控制语句。
升级前备份关键数据,并评估对象锁和业务影响。
不直接修改已发布版本的安装脚本,应通过新版本发布变更。