PostgreSQL中pg_catalog自定义函数未被pg_dump/pg_upgrade捕获的问题
PostgreSQL pg_catalog自定义函数导出/升级问题解答
1. 为何函数会被pg_dump或pg_upgrade跳过?
pg_dump的默认逻辑是只导出用户创建的非系统模式对象,而pg_catalog是PostgreSQL的核心系统模式,pg_dump默认将其归为系统对象范畴,会自动排除该模式下的自定义对象——这么做是为了避免误导出或覆盖系统自带的核心对象。
pg_upgrade内部依赖pg_dump和pg_restore完成数据迁移,自然继承了这个排除规则,所以你的自定义函数不会被纳入升级后的集群。
2. 在pg_catalog中创建自定义函数是否安全?
不安全,强烈不建议这么做,核心原因有三点:
- 升级风险:PostgreSQL版本升级时会对
pg_catalog进行更新(比如新增系统函数、调整系统对象定义),你的自定义函数可能被覆盖,甚至直接导致升级流程报错中断。 - 维护风险:自定义函数和系统函数同处一个模式,后续排查问题、迭代功能时极易混淆,增加维护成本。
- 权限风险:
pg_catalog的默认权限设置可能导致普通用户也能访问你的自定义函数,带来不必要的权限泄露隐患。
3. 如何确保此类函数被包含在导出和升级流程中?
最优方案:迁移到用户自定义模式
这是最规范且安全的做法:
- 创建专属用户模式:
CREATE SCHEMA my_custom_utils;
- 将函数迁移到新模式(先删除原函数,再重新创建到新模式):
DROP FUNCTION IF EXISTS pg_catalog.my_custom_func(); CREATE FUNCTION my_custom_utils.my_custom_func() RETURNS text AS $$ BEGIN RETURN 'custom logic'; END; $$ LANGUAGE plpgsql;
迁移完成后,pg_dump默认会导出这个用户模式下的所有对象,升级流程也会自动包含该函数。
若必须保留在pg_catalog(不推荐)
- pg_dump导出时:需显式指定导出
pg_catalog下的目标函数,命令如下:
pg_dump mydb --function=pg_catalog.my_custom_func > mydb_dump.sql
也可以导出整个pg_catalog模式(注意:会导出所有系统对象,后续导入时可能引发冲突,谨慎使用):
pg_dump mydb -n pg_catalog > mydb_dump.sql
- pg_upgrade时:可以提前在目标集群手动创建该函数,或者先用上述pg_dump命令导出函数,待升级完成后再导入到新集群中。
内容的提问来源于stack exchange,提问作者manasa
相关产品推荐
相关产品推荐

