PostgreSQL 15导入9.5备份时plperl与lc_monetary兼容问题
问题分析与解决办法
问题现象
- 将PostgreSQL 9.5的备份导入PostgreSQL 15环境后,创建
plperl扩展时,插入money类型字段会触发错误:ERROR: invalid input syntax for type money - 禁用
plperl扩展可正常导入备份,导入完成后手动执行插入操作也能成功
根因定位
问题核心是系统locale的lc_monetary配置变化:新Linux系统中de_AT locale的千位分隔符已从普通空格(<U0020>)改为非断空格(<U202F>)。
- PostgreSQL 9.5时期使用普通空格作为千位分隔符,备份文件中
money类型数据的格式化完全基于该规则 - PostgreSQL 15搭配新系统locale时,
plperl扩展会继承当前系统的lc_monetary配置,导致解析备份中旧格式的money数据时出现语法错误 - 禁用
plperl或手动插入时,PostgreSQL会使用自身默认解析逻辑,可兼容旧格式的money数据
临时解决方案
- 自建PostgreSQL 9.5容器:由于官方PostgreSQL 9.5镜像已停止维护,可修改历史Dockerfile构建可用的9.5容器,在该容器内完成备份导入,再通过
pg_dump(全量导出或仅导出数据)的方式迁移到PostgreSQL 15,规避locale差异带来的解析问题 - 临时调整locale配置:若系统支持旧版本
de_ATlocale包,可在PostgreSQL 15环境中临时将lc_monetary切换为旧规则配置,导入完成后再恢复原有设置
长期解决方案
彻底替换money类型为numeric类型:
money类型高度依赖系统locale,跨版本、跨环境迁移时极易出现兼容性问题- 执行字段类型变更SQL(按需调整精度):
ALTER TABLE 你的表名 ALTER COLUMN 金额字段名 TYPE numeric(19,2) USING 金额字段名::numeric; - 后续业务逻辑中统一使用
numeric类型存储金额数据,从根源避免locale相关的兼容性问题
内容的提问来源于stack exchange,提问作者Martin Zeller
相关产品推荐
相关产品推荐

