帮你快速理解、总结文档立即下载
文档中心>云数据库 PostgreSQL>操作指南>插件管理>PostgreSQL 租户自定义扩展功能使用说明

PostgreSQL 租户自定义扩展功能使用说明

最近更新时间:2026-09-16 10:48:56
我的收藏

一、功能概述

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 语言,并满足固定签名、STRICTIMMUTABLE 等要求。
安装和升级脚本不能包含 BEGINCOMMIT 等事务控制语句;其整体事务由 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 实例版本支持该功能

登录 云数据库 PostgreSQL 控制台,确认目标实例版本已支持租户自定义扩展功能。实际支持的 PostgreSQL 版本、pg_tle 版本和地域以控制台展示为准。
连接目标数据库后,可以执行以下 SQL 检查服务器是否提供 pg_tle
SELECT name, default_version, installed_version
FROM pg_catalog.pg_available_extensions
WHERE 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, extversion
FROM pg_catalog.pg_extension
WHERE extname = 'pg_tle';
预期返回一条 pg_tle 记录。
如果需要在多个数据库中使用租户自定义扩展功能,应在每个目标数据库中分别执行 CREATE EXTENSION pg_tle

2.5 授予扩展管理权限

由具备角色管理权限的账号执行:
GRANT pgtle_admin TO extension_admin;
其中,extension_admin 替换为实际扩展管理账号。
如果希望把权限授予当前登录账号,可以执行:
DO $grant_pgtle_admin$
DECLARE
target_role name := CURRENT_USER;
BEGIN
EXECUTE pg_catalog.format(
'GRANT pgtle_admin TO %I',
target_role
);
END
$grant_pgtle_admin$;
检查当前账号是否已获得显式授权:
SELECT EXISTS (
SELECT 1
FROM pg_catalog.pg_auth_members AS am
JOIN pg_catalog.pg_roles AS granted_role
ON granted_role.oid = am.roleid
JOIN pg_catalog.pg_roles AS member_role
ON member_role.oid = am.member
WHERE 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 precision
LANGUAGE sql
AS $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 precision
LANGUAGE sql
AS $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 precision
LANGUAGE sql
AS $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 查询已注册扩展

查询扩展控制信息:
SELECT
name,
default_version,
schema,
requires,
comment
FROM pgtle.available_extensions()
WHERE name = 'tle_distance_demo';
关键结果应为:
name = tle_distance_demo
default_version = 0.1
schema = tle_distance_demo
requires = {pg_tle}
pg_tle 会自动加入依赖列表,无需手动声明。
查询可用版本:
SELECT
name,
version,
schema,
requires,
comment
FROM 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, extversion
FROM pg_catalog.pg_extension
WHERE 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。业务计算逻辑不变,但为函数增加 IMMUTABLEPARALLEL 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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $function$
SELECT tle_distance_demo.distance(x1, y1, x2, y2, 2);
$function$;
$update_0_1_to_0_2$
);
成功时返回 t

4.2 查询升级路径

SELECT source, target, path
FROM 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_version
FROM pgtle.available_extensions()
WHERE name = 'tle_distance_demo';
预期 default_version0.2

4.4 升级扩展

执行 PostgreSQL 标准命令:
ALTER EXTENSION tle_distance_demo UPDATE;
也可以显式指定目标版本:
ALTER EXTENSION tle_distance_demo UPDATE TO '0.2';
确认当前安装版本:
SELECT extname, extversion
FROM pg_catalog.pg_extension
WHERE 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 = 8
euclidean = 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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $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 precision
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $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, path
FROM pgtle.extension_update_paths('tle_distance_demo')
ORDER BY source, target;

5.4 查询已经创建的扩展

SELECT extname, extversion
FROM pg_catalog.pg_extension
ORDER BY extname;

5.5 查询扩展对象

SELECT
e.extname,
object_info.type AS object_type,
object_info.schema AS schema_name,
object_info.name AS object_name,
object_info.identity AS object_identity
FROM pg_catalog.pg_extension AS e
JOIN pg_catalog.pg_depend AS d
ON d.refclassid = 'pg_catalog.pg_extension'::regclass
AND d.refobjid = e.oid
AND d.deptype = 'e'
CROSS JOIN LATERAL pg_catalog.pg_identify_object(
d.classid,
d.objid,
d.objsubid
) AS object_info
WHERE e.extname = 'tle_distance_demo'
ORDER BY
object_info.type,
object_info.schema,
object_info.name,
object_info.identity;
函数等非 pg_class 对象不会出现在上述结果中。可以单独查询扩展 Schema 下的函数:
SELECT
n.nspname AS schema_name,
p.proname AS function_name,
pg_catalog.pg_get_function_identity_arguments(p.oid) AS arguments
FROM pg_catalog.pg_proc AS p
JOIN pg_catalog.pg_namespace AS n
ON n.oid = p.pronamespace
WHERE 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 1
FROM pgtle.available_extensions()
WHERE name = 'tle_distance_demo'
) AS extension_registration_removed;
预期返回 t

七、进阶使用:创建自定义基础类型

本章创建一个名为 cloud_email 的自定义类型。该类型在数据写入时检查邮箱格式,并统一转换为小写后保存。
自定义基础类型具有以下限制:
内部数据使用 bytea 表示。
输入函数签名必须为 text -> bytea
输出函数签名必须为 bytea -> text
输入输出函数必须为 STRICTIMMUTABLE
输入输出函数必须使用 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 bytea
LANGUAGE plpgsql
IMMUTABLE
STRICT
AS $function$
BEGIN
IF input !~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[.][A-Za-z]{2,}$' THEN
RAISE EXCEPTION 'invalid email address: "%"', input
USING 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 text
LANGUAGE sql
IMMUTABLE
STRICT
AS $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::text
FROM tle_type_demo.contacts
ORDER BY id;
预期结果:
1 | alice.example@example.com
2 | 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_name
FROM pg_catalog.pg_auth_members AS am
JOIN pg_catalog.pg_roles AS granted_role
ON granted_role.oid = am.roleid
JOIN pg_catalog.pg_roles AS member_role
ON member_role.oid = am.member
WHERE 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 函数:
SELECT
n.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_type
FROM pg_catalog.pg_proc AS p
JOIN pg_catalog.pg_namespace AS n
ON n.oid = p.pronamespace
WHERE 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_extensions
WHERE 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_nameextension_user 替换为实际名称。

10.5 升级时提示找不到升级路径

执行以下 SQL 查询已注册升级路径:
SELECT source, target, path
FROM 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。
两个函数均声明为 STRICTIMMUTABLE
两个函数使用 trusted 过程语言。
当前用户拥有函数和 shell type。
当前用户是 pgtle_admin 成员。
当前用户对目标 Schema 有 CREATE 权限。

十一、使用建议

11.1 发布前验证

建议在测试数据库完成以下验证后再发布到生产数据库:
1. 从空数据库安装扩展。
2. 调用扩展所有主要函数。
3. 从每个受支持旧版本升级。
4. 模拟升级脚本执行失败并确认事务回滚。
5. 检查扩展对象权限。
6. 检查 DROP EXTENSION 的依赖影响。
7. 检查备份恢复和主备切换后的扩展可用性。

11.2 命名建议

扩展名称使用小写字母、数字和下划线。
避免与 PostgreSQL 内置扩展同名。
为扩展使用独立 Schema。
函数和类型使用 Schema 限定名。
版本号使用稳定、可比较的格式,如 1.01.12.0
安装脚本和升级脚本中避免依赖不确定的 search_path

11.3 权限建议

只向可信账号授予 pgtle_admin
普通业务账号仅授予扩展对象所需的 USAGEEXECUTESELECT 等权限。
不使用扩展脚本修改无关角色或对象。
不在扩展脚本中保存密码、密钥或其他敏感信息。
定期审计扩展版本、注册信息和角色成员。

11.4 升级建议

每个生产版本都保留完整安装脚本。
为相邻版本提供明确升级路径。
升级脚本尽量使用可重复验证的 DDL。
不在升级脚本中执行事务控制语句。
升级前备份关键数据,并评估对象锁和业务影响。
不直接修改已发布版本的安装脚本,应通过新版本发布变更。