2013-01-24 28 views
0

PostgreSQL的9.1 2.0.12 Npgsql的插入大對象移植到PostgreSQL返回53200內存不足的錯誤

我有二進制數據,我想在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的內存設置到值調整的所有方式:

  • 的shared_buffers
  • work_mem
  • maintenance_work_mem

到目前爲止我發現postgresql是一個偉大的數據庫系統,但這是目前的展示瓶塞,我不能似乎將這個大小的文件放入數據庫中。我真的不想處理手動將文件分塊,並重新創建客戶端,如果我可以幫助它。

請幫忙!?

回答

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

嘗試減少max_connections的數量以爲需要執行一個700MB操作的少數連接保留內存。將work_mem(每個操作可用的內存)增加到1GB。試圖在一個字段中填充700MB聽起來很奇怪。

將shared_buffers大小增加到4096MB。

+0

減少的max_connections = 4(postgresql不會以少於此數開始)。不用找了。增加shared_buffers = 1000MB(postgresql不會以比此更高的開始)。不用找了。這些數據存儲文件(二進制數據)。有一個特別大的文件,我試圖存儲。 – Jayden