0

Postgresql 9.1 NPGSQL 2.0.12

我有想要存储在 postgresql 数据库中的二进制数据。大多数文件加载正常,但是,大型二进制 (664 Mb) 文件会导致问题。当尝试通过 Npgsql 使用大对象支持将文件加载到 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 是一个很棒的数据库系统,但目前这是一个显示停止器,我似乎无法将这个大小的文件放入数据库。如果可以的话,我真的不想手动将文件切成块并重新创建客户端。

请帮忙!?

4

2 回答 2

2

我认为答案似乎是用字节数组的块迭代地调用 LargeObject 类的 Write() 方法。我知道我说过我不想处理数据分块,但我真正的意思是将数据分块成单独的大对象。这个解决方案意味着我将数组分块,但它仍然作为一个对象存储在数据库中,这意味着我不必跟踪文件部分,只需跟踪一个 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)
于 2013-01-24T22:14:33.840 回答
1

尝试减少 max_connections 的数量,以便为需要执行 700MB 操作的少数连接保留内存。将 work_mem(每次操作可用的内存)增加到 1GB。试图将 700MB 塞进一个字段听起来很奇怪。

将 shared_buffers 大小增加到 4096MB。

于 2013-01-24T20:33:45.227 回答