Ubuntu 18.04下sqsh执行SELECT时出现dsp_desc_bind内存分配失败求助
dsp_desc_bind: Memory allocation failure for column #1 错误成因 我来帮你拆解这个错误的可能成因,结合你使用的Ubuntu 18.04、FreeTDS 1.00.82-2和SQSH 2.1.7-4build1版本来看,主要有以下几个核心方向:
NVARCHAR类型的字符集/编码不匹配
FreeTDS的字符集配置如果和SQL Server中NVARCHAR的UTF-16编码不兼容,很容易引发内存分配计算错误。比如默认用单字节编码(如iso-8859-1)处理双字节的NVARCHAR数据时,FreeTDS在计算所需缓冲区大小会出现偏差,要么分配的内存不够,要么计算出一个不合理的数值导致分配失败。你用的FreeTDS 1.00.82是Ubuntu 18.04自带的旧版本,对NVARCHAR的UTF-16处理存在已知的老bug,尤其是当列包含特殊字符或较长内容时更容易触发。SQSH与FreeTDS的版本适配问题
SQSH依赖FreeTDS的API来完成查询结果集的列绑定操作,如果两者在数据类型映射的逻辑上存在不一致,比如SQSH请求的缓冲区大小和FreeTDS计算的内存需求不匹配,就会触发这个内存分配失败的错误。你使用的SQSH版本和FreeTDS版本组合可能存在未被修复的兼容性问题。FreeTDS内部的内存计算bug
在旧版本的FreeTDS中,针对NVARCHAR列的长度计算存在逻辑错误。比如当列是NVARCHAR(MAX)或者定义了较长的固定长度时,FreeTDS在计算所需内存时可能出现数值溢出,或者算出一个超出系统合理范围的数值,导致底层的内存分配函数(如malloc/calloc)执行失败,进而抛出dsp_desc_bind: Memory allocation failure for column #1的错误。系统内存不足(可能性较低)
虽然这个错误提示是内存分配失败,但如果系统真的处于极低内存状态,也可能触发该问题。不过这种情况通常会伴随系统层面的OOM(内存不足)日志,而且针对单列的内存分配失败概率相对较低,所以可以放在最后排查。
如果要验证这些推测,你可以试试这几个小步骤:
- 修改FreeTDS配置文件
/etc/freetds/freetds.conf,将对应连接的charset设置为UTF-8或UCS-2,然后重新执行查询; - 用FreeTDS自带的
tsql工具执行同样的SELECT foo FROM bar语句,看是否会出现相同错误,以此区分是FreeTDS本身的问题还是SQSH的适配问题。
内容的提问来源于stack exchange,提问作者unhammer

