tds_fdw PostgreSQL 外部表将大文本截断为 2048 个字符

Posted

技术标签:

【中文标题】tds_fdw PostgreSQL 外部表将大文本截断为 2048 个字符【英文标题】:tds_fdw PostgreSQL Foreign Table Truncates Large Text to 2048 Characters 【发布时间】:2021-12-09 02:12:30 【问题描述】:

我已经创建了几个外部表,它们都可以正常工作,但现在我必须处理一个表,该表的某些行中包含 20-30 KB 的文本。如果该文本很小,则会完整呈现,但如果它恰好超过 2048 个字符,则将其余部分截断。

我的 tds_fdw 设置:

CREATE SERVER mssql_srv
FOREIGN DATA WRAPPER tds_fdw
OPTIONS (servername 'mssql_srv.my_domain.com', port '1433', database 'MY_DB', msg_handler 'blackhole');

ALTER SERVER mssql_srv OWNER TO my_user;

CREATE USER MAPPING FOR my_user
SERVER mssql_srv
OPTIONS (username 'my_user', password 'xxxxxxxx');

CREATE FOREIGN TABLE my_large_table (
  ID VARCHAR (64),
  FULL_TEXT TEXT)
SERVER vsql_tx
OPTIONS (schema_name 'dbo', table_name 'my_large_table', row_estimate_method 'showplan_all');

是的,MSSQL 端的列名是大写的。它们的数据类型是:

ID nvarchar(64)
FULL_TEXT nvarchar(max)
SELECT * FROM my_large_table;

返回 FULL_TEXT 的部分值。

对于每个截断的字段:

SELECT LENGTH(full_text) FROM my_large_table WHERE ID = '50166cd8ed2266e0c8d15d9161477c3d636f193e873c4a97a6309cff237d8f0';
 
 length 
--------
   2048
(1 row)

当我尝试使用 tsql(FreeTDS 实用程序)选择相同的值时,它会返回整个值,即使超过 20 KB 也不会截断。

我还有另一个 PostgreSQL 服务器,它有一个类似的表,有很长的文本记录。我尝试使用 postgres_fdw 连接到它,同样,没问题,没有截断。

有什么想法可能是错误的或需要检查什么吗? 谢谢。

服务器设置: Debian 11.1 PostgreSQL 13.4-4.pgdg110+1 tds_fdw:2.0.2-2.pgdg110+1 freetds 通用:1.2.3-1 libsybdb5:amd64: 1.2.3-1

Microsoft SQL Server 2014 (SP2-CU14) (KB4459860) - 12.0.5600.1 (X64) 2018 年 9 月 27 日 21:47:31 版权所有 (c) 微软公司 Windows NT 6.3(内部版本 14393:)(管理程序)上的企业版(64 位)

Windows 2016 标准版

【问题讨论】:

你能检查一下text size 在你的 FreeTDS 设置中为 FDW 设置了什么吗?我已经看到这与以前的主要 FreeTDS 设置不同。 freetds.org/userguide/freetdsconf.html @FlipperPA 感谢您提出覆盖 FreeTDS 设置的想法。我仍然找不到在哪里,但创建一个明确声明默认“文本大小 = 4294967295”的 /var/lib/postgresql/.freetds.conf 文件最终允许我选择全文。当然,在哪里覆盖了默认的 FreeTDS 设置仍然是一个问题。 【参考方案1】:

感谢@FlipperPA。 总之,我采取的解决方案是将/etc/freetds/freetds.conf或/var/lib/postgresql/.freetds.conf的“文本大小”参数设置为最大值(4294967295):

[global]
...
tds version = auto
...
text size = 4294967295
...

尚不完全清楚为什么需要这样做:FreeTDS 文档指出这已经是默认设置,并且 tsql 不会受到截断的影响。我也找不到 tds_fdw 比主要文件更喜欢的任何其他 freetds.conf 文件。也许 tds_fdw 有自己的默认值,可以被 freetds.conf 覆盖。无论解释如何,设置上述参数都有效。

【讨论】:

在我看来,您系统上某处的 freetds.conf 文件已将其设置为较低的值,可能是 PostgreSQL 外部数据包装器的一部分:在 Linux 上,可能值得一看对于有问题的freetds.conf 文件,使用如下命令:find / -name "*freetds.conf*" 在配置中集中进行更改。 我做了类似的搜索。这会找到: /usr/share/man/man5/freetds.conf.5.gz - 手册页,/usr/share/doc/freetds-common/examples/freetds.conf.pl - 用于转换旧的“接口”文件 > freetds.conf, /usr/share/doc/freetds-common/examples/freetds.conf - 一个示例文件,/usr/share/freetds/freetds.conf - 可能是唯一的其他文件可以读取 /etc/freetds/freetds.conf -- 主 conf 文件。它们都不包含“2048”或活动的“文本大小”行。 我也查看了postgresql-13-tds-fdw包安装的所有文件,没有conf文件,即使是其他名字。

以上是关于tds_fdw PostgreSQL 外部表将大文本截断为 2048 个字符的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql fillfactor

PostgreSQL外部数据

在 Postgresql 中进行水平分区的正确步骤是啥?

java处理大文本方案

PostgreSQL 参数调整(性能优化)

如何使用 RECORD 在 PostgreSQL 中返回多行?