PostgreSQL 18: file_fdw 新增 on_error 与 log_verbosity 选项

John Doe 十一月 27, 2025

使用 COPY 加载数据到 PostgreSQL 时,单行出错会导致整个加载过程失败回滚。虽然 PostgreSQL 17 中,COPY 命令引入了 on_error 选项,但是可处理的错误还是受限的。

image

特性提交日志

file_fdw:为 file_fdw 新增 on_error 与 log_verbosity 选项。

在 PostgreSQL 17 版本中,COPY命令引入了on_errorlog_verbosity选项。本次提交将这两个选项的支持扩展到了file_fdw(文件外部数据包装器)。

file_fdw外部表设置on_error = 'ignore'后,即使用户查询的输入文件中包含格式错误的行,系统也会跳过这些存在问题的行,从而确保查询能够正常执行且不报错。

on_errorlog_verbosity这两个选项,均适用于对file_fdw外部表执行的SELECT查询和ANALYZE操作。

讨论:https://postgr.es/m/ab59dad10490ea3734cf022b16c24cfd@oss.nttdata.com

示例

在 PostgreSQL 中,file_fdw是最常用的外部数据包装器之一,它能将本地文件(如 CSV、文本文件)挂载为数据库外部表,让用户可以通过标准 SQL 直接查询文件数据,广泛应用于日志分析、数据预览、ETL 数据抽取等场景。但在 PostgreSQL 18 之前,file_fdw存在一个明显痛点:如果外部文件中包含格式错误、数据类型不匹配的行,查询会直接报错中断,必须手动清理文件后才能重新执行,严重影响数据处理效率。

PostgreSQL 18 通过本次提交解决了这一问题,为file_fdw新增on_errorlog_verbosity选项,让外部表查询具备了异常数据容错能力和日志粒度控制,大幅提升了处理外部数据的灵活性。

例如,某系统的 Nginx 访问日志按天导出为 CSV 文件,通过file_fdw挂载为外部表nginx_logs,用于实时查询访问量、热门接口等指标。但日志采集过程中,偶尔会出现个别格式错乱的行(如字段缺失、时间格式异常),导致查询直接报错。

我们需要跳过异常行,正常查询有效的日志数据,同时记录跳过的异常行数,便于后续排查问题。

1. 创建基础外部表(假设日志文件包含ipaccess_timeuristatus字段):

CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw;

CREATE FOREIGN TABLE nginx_logs (
    ip TEXT,
    access_time TIMESTAMP,
    uri TEXT,
    status INT
) SERVER file_server
OPTIONS (
    filename '/data/logs/nginx_20241003.csv',
    format 'csv',
    header 'on', -- 日志文件第一行为字段名
    delimiter ','
);

2. 测试默认行为(无on_error选项):

SELECT COUNT(*) FROM nginx_logs;
ERROR:  invalid input syntax for type timestamp: "2025-10-03 14:30:xx"
CONTEXT:  COPY nginx_logs, line 156, column access_time: "2025-10-03 14:30:xx"

3. 添加异常处理选项:

-- 跳过错误行,保留默认日志输出(显示跳过行数)
ALTER FOREIGN TABLE nginx_logs OPTIONS (
    ADD on_error 'ignore',
    ADD log_verbosity 'default'
);

4. 重新执行查询:

SELECT COUNT(*) FROM nginx_logs;
NOTICE:  2 rows were skipped due to data type incompatibility
 count
-------
 12583
(1 row)

查询正常完成,返回有效日志总行数;通过NOTICE得知有 2 行异常数据,既不中断实时分析,也不降低数据监控质量。

file_fdwon_errorlog_verbosity特性,实现了 PostgreSQL 处理外部文件的容错能力。它让用户无需再为少量异常数据中断查询、手动清理文件,而是通过灵活的配置实现“容错执行+日志监控”,大幅提升了日志分析、数据预览、自动化 ETL 等场景的效率和稳定性。对于经常与外部文件交互的 PostgreSQL 用户来说,这是 PostgreSQL 18 中极具实用价值的一个更新。

非常不错的新特性,这样 PostgreSQL 导入数据的容错性更高了。感谢社区的所有相关人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/a1c4c8a9e1e3a53996dafa1f4ee6d4f7de2c58b2