pg_clickhouse 0.11.0:把字符编码校验带进跨数据库查询

2026-10-01 26 预计阅读时间: 1 分钟
来源: postgr.es AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:7 分钟

pg_clickhouse v0.11.0 和 chdb v0.1.2 已发布到 GitHub 与 PGXN。这一轮更新继续围绕跨数据库兼容性展开,相关能力大量来自 header-only C 库 clickhouse-c 与 pg-clickhouse-c。

其中一个容易被低估、却会直接影响生产稳定性的变化,是文本和 JSON 数据的字符编码校验。对于通过外部表读取 ClickHouse 数据的 PostgreSQL 用户来说,编码问题不应该等到查询结果进入应用后才暴露。

问题不只是乱码

在开发 chdb 扩展基准测试时,项目发现 pg-clickhouse-c 此前没有验证文本列中的字符编码。这样一来,包含非法字节的数据可能顺利穿过底层库,直到更晚的阶段才触发异常,甚至表现为乱码、解析失败或下游应用错误。

修复后的行为是:当文本类型或基于 JSON 的类型包含违反数据库编码约束的字节时,底层库会抛出异常。chdb v0.1.1 已经包含这项修复,而 pg_clickhouse 则延后到 v0.11.0 发布,以避免已有外部表因为历史脏数据突然全部失败。

这个发布节奏很有价值:数据正确性修复本身并不复杂,但把它直接应用到已有外部表,可能改变线上查询行为。因此,兼容性修复还需要一个可控的启用方式。

check_encoding:把行为交给外部服务器配置

pg_clickhouse v0.11.0 增加了新的 foreign server 选项 check_encoding,用于提供编码错误处理策略。它的意义不只是“增加一个开关”,而是把错误处理从库内部默认行为提升为数据库管理员可以审查、配置和逐步推广的策略。

升级时建议先检查现有 foreign server 的配置:

psql "$DATABASE_URL" -c "
SELECT srvname, srvoptions
FROM pg_foreign_server
ORDER BY srvname;
"

如果需要修改某个外部服务器,可以使用 PostgreSQL 的 ALTER SERVER。下面的命令展示了配置位置;<encoding_handler> 需要替换为 pg_clickhouse v0.11.0 文档中支持的具体错误处理值:

ALTER SERVER clickhouse_prod
OPTIONS (ADD check_encoding '<encoding_handler>');

如果该服务器已经存在同名选项,应使用 SET 而不是 ADD:

ALTER SERVER clickhouse_prod
OPTIONS (SET check_encoding '<encoding_handler>');

这里不要直接把占位符当成实际值部署。不同错误处理策略会影响非法字节是被拒绝、报告,还是以其他方式处理;生产环境应先在测试库验证,并以该版本的扩展文档为准。

一套更稳妥的升级流程

可以把升级拆成三个阶段。

1. 盘点风险数据

先找出会经过外部表传输的文本和 JSON 列,并确认目标 PostgreSQL 数据库编码。对于历史数据来源复杂、经过多次导入的数据集,应优先抽样检查,而不是默认所有数据都符合编码约束。

2. 在隔离环境启用校验

使用与生产相同的扩展版本、数据库编码和外部表定义,在测试环境配置 check_encoding。重点验证包含文本和 JSON 类型的查询,包括过滤、排序、聚合以及应用实际使用的查询路径。

一个最小的回归检查可以这样执行:

set -euo pipefail

psql "$DATABASE_URL" -v ON_ERROR_STOP=1 <<'SQL'
SELECT current_database(), pg_encoding_to_char(encoding)
FROM pg_database
WHERE datname = current_database();

SELECT srvname, srvoptions
FROM pg_foreign_server
WHERE srvname = 'clickhouse_prod';
SQL

3. 再推广到已有外部表

确认异常能够被监控和定位后,再将配置推广到生产。特别要关注应用是否把编码异常误判为普通的“无数据”,以及连接池、批处理任务和定时作业是否拥有明确的失败重试策略。

兼容性修复也需要边界

编码校验能更早暴露脏数据,但它不会替你修复数据。启用后出现错误时,应区分三类问题:数据源确实包含非法字节、数据库编码与业务预期不一致,或者外部表字段类型映射不正确。

还要注意版本范围:chdb v0.1.1 已包含底层修复,pg_clickhouse 则在 v0.11.0 通过 check_encoding 提供配置入口。升级时应分别核对扩展版本、外部服务器选项和已有外部表的行为,避免只更新二进制却忽略配置变更。

落地检查清单

  • 确认已安装 pg_clickhouse v0.11.0 或更高版本。
  • 记录现有 foreign server 的 srvoptions。
  • 明确数据库编码,以及文本和 JSON 数据的来源。
  • 在测试环境验证 check_encoding 的具体处理策略。
  • 对包含历史脏数据的外部表执行真实查询回归。
  • 为编码异常增加日志、告警和可定位的失败信息。
  • 生产启用前确认应用不会吞掉或错误转换该异常。

这类改动的价值不在于让所有查询“看起来还能跑”,而在于让跨数据库传输的数据边界更加明确。对新建外部表,可以尽早纳入编码校验;对已有表,则应利用 check_encoding 分阶段迁移,把正确性提升和运行风险控制放在同一个发布计划里。


相关推荐