Subject: [postgresql-interfaces/psqlodbc] issue #96: Memory allocation error from PSQLODBC35W.DLL

From: "ezekieloyeniran1 (@ezekieloyeniran1)" <[email-masked]>
Date: Mon, 10 Mar 2025 19:44:11 +0000

I am currently experiencing an out-of-memory (OOM) error while using Copy Activity in a Pipeline to transfer 100M+ records from an On-Prem PostgreSQL database to a Microsoft Fabric Lakehouse.
 
The pipeline works for smaller subsets (~1M records) with parallelism set to 10 but consistently fails when attempting to load over 1 million records.
 
The PostgreSQL source is connected via ODBC (psqlodbc35w.dll), and an On Prem Data Gateway (version 3000.246.5) with 4 logical processors.  
 
I would love an insight on knowing the limitation on the volume of data PSQLODBC35W.DLL driver can handle. 

Do you think the constraints is from the On-Prem Data Gateway to transfer large data via Microsoft On-Prem Data Gateway? 

Are there best practices for optimizing PostgreSQL reads to prevent failures?

Appreciate any insights!

Here is the error I got:
"```
_{
	"errorCode": 2200,
	"message": "Failure happened on 'Source' side. ErrorCode=UserErrorOdbcOperationFailed,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=ERROR [HY001] Out of memory while reading tuples.;\nmemory allocation error???,Source=Microsoft.DataTransfer.Runtime.GenericOdbcConnectors,''Type=System.Data.Odbc.OdbcException,Message=ERROR [HY001] Out of memory while reading tuples.;\nmemory allocation error???,Source=PSQLODBC35W.DLL,'",
	"details": []
}_"
```

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Fri, 14 Mar 2025 11:02:43 +0000

I don't think this is an ODBC error per-se. The issue is that the way the protocol works is that if you do `select * from some_large_table` all of the records are read into memory before they are returned to you. So ultimately, you require enough memory to hold your result set

---

From: "markmaker (@markmaker)" <[email-masked]>
Date: Wed, 21 May 2025 08:03:31 +0000

I had the same problem, and this is how I had to solve it:

1. Use the original query `where` expression etc. but only fetch the primary keys of the result set records. Assuming the primary key is some rather small ID data type, it will allow for very large result sets, even in constrained RAM.
2. Then select the actual records in batches of a comfortable size, i.e. `select ... where yourPrimaryKey in (?, ?, ?, ?, ...)`

This seems to work well, PostgreSQL does the batch fetching fast (as it happens, the overall performance is still faster than the original DB we used before). We even just prepare one batch fetching statement, and fill any surplus bound params with `null` for the last remainder fetch, and it doesn't seem to bother.

During the query processing, if you are updating or even deleting records further down the data set, be aware this will now be reflected in the batch-fetched records, unlike with the original full-fetch query. We actually wanted that, it solved a secondary problem for us.

_Mark