Postgresql 9.1 NPGSQL 2.0.12
我想要存储在postgresql数据库中的二进制数据。大多数文件加载正常,但是,大型二进制(664 Mb)文件导致问题。当尝试通过Npgsql使用Large Object支持将文件加载到postgresql时,postgresql服务器返回“内存不足”错误。
我目前正在使用4Gb RAM的工作站上运行它,2Gb可用,而postgresql在空闲状态下运行。
这是我正在使用的代码,改编自PG Foundry Npgsql User's Manual。
using (var transaction = connection.BeginTransaction())
{
try
{
var manager = new NpgsqlTypes.LargeObjectManager(connection);
var noid = manager.Create(NpgsqlTypes.LargeObjectManager.READWRITE);
var lo = manager.Open(noid, NpgsqlTypes.LargeObjectManager.READWRITE);
lo.Write(BinaryData);
lo.Close();
transaction.Commit();
return noid;
}
catch
{
transaction.Rollback();
throw;
}
}
我已经尝试将postgresql的内存设置从默认值修改为调整所有值的方式:
到目前为止,我发现postgresql是一个很棒的数据库系统,但这是目前的一个显示阻止,我似乎无法将这个大小的文件放入数据库。如果我能帮忙的话,我真的不想处理手动将文件分成块并重新创建客户端。
请帮忙!?
答案 0 :(得分:2)
我认为答案似乎是使用字节数组的块迭代地调用LargeObject类的Write()方法。我知道我说我不想处理数据分块,但我真正的意思是将数据分块为单独的LargeObjects。这个解决方案意味着我将数组块化,但它仍然作为一个对象存储在数据库中,这意味着我不必跟踪文件部分,只需要跟踪一个oid。
do
{
var length = 1000;
if (i + length > BinaryData.Length) length = BinaryData.Length - i;
byte[] chunk = new byte[length];
Array.Copy(BinaryData, i, chunk, 0, length);
lo.Write(chunk, 0, length);
i += length;
} (i < BinaryData.Length)
答案 1 :(得分:1)
尝试减少max_connections的数量,以便为需要执行700MB操作的少数连接保留内存。将work_mem(每次操作可用的内存)增加到1GB。试图将700MB塞入一个领域听起来很奇怪。
将shared_buffers大小增加到4096MB。