Chris van Eijk:PostgreSQL 中的“unrecognized configuration parameter”报错

Chris van Eijk:PostgreSQL 中的“unrecognized configuration parameter”报错

💡 原文英文,约1700词,阅读约需7分钟。
📝

内容提要

PostgreSQL 报错“unrecognized configuration parameter”的常见成因是将 pg_dump 17+ 的备份恢复到 16 及更旧版本,因 transaction_timeout 参数不存在而报错。普通 psql/pg_restore 会报错但继续导入数据,加 --single-transaction 或 ON_ERROR_STOP 则全部失败。修复方法是删除 dump 中该 SET 行,或使用同版本 pg_dump。其他原因包括已移除的 lc_collate、MySQL 命令、psql 变量 autocommit 及未设置的自定义参数。

🔎

延伸解读

恢复方式决定数据是否落地

文章实测显示,将 pg_dump 17 的备份恢复到 PostgreSQL 16 时,普通 psql 或 pg_restore 会报错但继续导入数据;而加上 --single-transaction 或 ON_ERROR_STOP 则会导致全部失败。尤其要注意,psql --single-transaction 在未加 ON_ERROR_STOP 时退出码为 0 却什么都没恢复,脚本若只检查退出码会误判成功。

postgresql.conf 中的同一参数更危险

若在 16 版本的 postgresql.conf 中写入 transaction_timeout,reload 会记录错误并拒绝应用文件中的任何其他更改,且只有日志会提示;重启则直接导致服务器无法启动。因此从 17 或 18 复制配置文件到旧版本时,需确认该行是否被注释掉,默认文件中它是注释状态。

自定义参数需用带默认值的读取方式

对于 app.tenant_id 这类自定义参数,在会话中未设置前直接 SHOW 或 current_setting 会报错。应使用 current_setting('app.tenant_id', true),未设置时返回 NULL 而非错误。另外,参数名必须包含点号,SET tenant_id = 5 会失败;RESET 后返回空字符串而非 NULL,策略中做类型转换时需留意。

其他常见误用与排查方向

报错中的参数名可帮助定位原因:lc_collate 和 lc_ctype 在 PostgreSQL 16 已移除,应从 pg_database 读取 datcollate 和 datctype;SHOW TABLES 等是 MySQL 命令,PostgreSQL 的 SHOW 只读取设置;autocommit 是客户端行为,psql 中用 \set AUTOCOMMIT off。若参数名拼写近似正确,PostgreSQL 不会提示正确名称,需查 pg_settings。

❓

Q&A

PostgreSQL 报错 unrecognized configuration parameter 是什么意思?

表示 PostgreSQL 不认识引号中的配置参数名,SQLSTATE 为 42704。常见于 SET、SHOW、current_setting() 或 postgresql.conf 中引用了服务器不存在的设置。

把 pg_dump 17 的备份恢复到 PostgreSQL 16 时报 transaction_timeout 错误,数据还能导入吗?

取决于恢复方式:普通 psql 或 pg_restore 会报错但继续导入数据;使用 --single-transaction、ON_ERROR_STOP 或 --exit-on-error 则不会导入任何数据。

如何修复因 transaction_timeout 导致的恢复报错?

最干净的方法是使用与目标服务器相同大版本的 pg_dump。若只有新版本 dump,可编辑纯文本 dump 删除 SET transaction_timeout 行(如 sed '/^SET transaction_timeout/d'),或对自定义格式先用 pg_restore -f 导出 SQL 再删除该行。

PostgreSQL 中 SHOW lc_collate 报错,应该怎么查排序规则?

lc_collate 和 lc_ctype 在 PostgreSQL 16 中已被移除。可查询 pg_database:select datcollate, datctype, datlocprovider from pg_database where datname = current_database();

在 PostgreSQL 里执行 SHOW TABLES 为什么报错?对应的命令是什么?

SHOW 在 PostgreSQL 中只读取配置参数,不支持 MySQL 的 SHOW TABLES。应使用 psql 的 \dt,或查询 information_schema.tables。

PostgreSQL 中 SET autocommit = off 报错,如何关闭自动提交?

autocommit 不是服务器设置,而是客户端行为。在 psql 中使用 \set AUTOCOMMIT off;在应用程序中应通过驱动或连接配置控制,而不是 SET。

自定义参数 app.tenant_id 在未设置时读取报错,如何避免?

使用 current_setting('app.tenant_id', true),未设置时返回 NULL 而不报错。注意参数名必须包含点号,且 RESET 后返回空字符串而非 NULL。

🏷️

标签

➡️

继续阅读