PostgreSQLIndex Plugin: Connection / Memory Leak

Hi friends!

We’ve got a couple of Orthanc instances on production! And more are expected to go live this year, yay! It’s awesome to see Orthanc run in in real world scenarios with real world data. It’s enlightening.

But I have observed over the last couple of weeks what I believe to be a memory leak, thus this e-mail is written.

It is not “strongly” related to Orthanc itself as far as I know. It’s related to the PostgreSQLIndex plugin. Let me explain:

Our setup for this stage of the project is pretty simple: our custom Orthanc storing files on disk and indexes in memory. Every five minutes the current “de facto” PACS server sends us new instances to be stored through DICOM.

What has been observed is that the memory consumption for one PostgreSQL process seemingly only grows. The production host has some 62.5GB of RAM and I’ve seen a particular postgres process reach 50GB+ at one time. The one associated with the one connection.

Has anyone experienced this? How did you deal with it?

Going back to the lab I was able to reproduce the problem with the postgresql-easy setup from Osimis’ samples. To reproduce it, fire the the compose file and start a non-stop stream of instances. You can use storescu with a large directory of DCM’s and the +sd and +r parameters of storescu.

Here’s a couple of screenshots illustrating this apparent leak:

Screenshot from 2019-07-12 16-26-39.png

Image #1: This was taken right before I started the sending of instances (15M of RES memory)

Screenshot from 2019-07-12 16-57-26.png

Image #2: This was taken at the end of the process (now it’s some 57MB)

Screenshot from 2019-07-12 17-01-43.png

Image #3: Orthanc’s memory consumption after the process was done. This image also show (in the second terminal) that roughly 6.4GB of instances were sent.

I’ve looked a little at both Orthanc and PostgreSQLIndex plugin source codes. What I’ve learned so far is it seems every time GetDatabase is called, PostgreSQLDatabase::open is as well but this connection is never closed. There are only two points in which PQfinish is called, both on orthanc-databases/Framework/PostgreSQL/PostgreSQLDatabase.cpp:

  • Line 62, during PostgreSQLDatabase::Close: There’s a message that greping our INFO-enabled logs fail to find.
  • Line 102, during PostgreSQLDatabase::Open: As part of a error condition, the PQfinish is called and a message is logged. Again, grep fails to find it.

I’m thinking that maybe our PostgreSQL setup need tuning but I’m not sure. Also, I could have the plugin close the connection but again I’m not sure. I could have a pgPool-II docker image sit between Orthanc and PostgreSQL as well. What I’m most likely to do is:

  • Have a pgPool-II docker image sit between Orthanc and PostgreSQL.
  • Have pgPool-II timeout idle connections.
  • If needed, rewrite the PostgreSQLDatabase::Open like the attachment. But I may experience issues should the connection be recreated during a DICOM burst.

Any ideas are mostly welcome!

Thanks in advance!

proposed-postgresqldatabase-open.cpp (1.22 KB)

Also worthy of notice, we’re running a custom Orthanc based off of Sébastien’s 1.5.6. Migrating to 1.5.7 is planned but since we’re during homologation phase, we can’t do that right now. Also, the Osimis image seems to run Orthanc 1.5.7 but I forgot to “docker pull osimis/orthanc-pro” before running the tests which means I will have to run them again since I previously had the old 1.5.6 version.

Screenshot from 2019-07-12 16-26-39.jpg

Screenshot from 2019-07-12 16-57-26.jpg

Screenshot from 2019-07-12 17-01-43.jpg

Hi Luiz,

Has this change already been integrated on your side ? It was the source of a memory leak and has been integrated in the PGSQL plugin version 3.2
https://bitbucket.org/sjodogne/orthanc-databases/commits/2d2b268799a26d6eec793f8c8f66d0feb5740c31

Screenshot from 2019-07-12 16-26-39.jpg

Screenshot from 2019-07-12 16-57-26.jpg

Screenshot from 2019-07-12 17-01-43.jpg

[forwarding since I inadvertently tried sending a large image]

[btw, thank you very much, Alain!]

Hi, Alain!

I just looked at the change and it seems our orthanc-databases needs refreshing. I’ll take the opportunity and upgrade.

Side-question: is Orthanc 1.5.7 database compatible with 1.5.6? I’m willing to take the time and upgrade our code base to the former since we’re based off of the later.

Thanks! =)

Screenshot from 2019-07-12 17-01-43.jpg

Screenshot from 2019-07-12 16-57-26.jpg

Screenshot from 2019-07-12 16-26-39.jpg

orthanc-databases is currently built using Orthanc SDK 1.5.4 so you should be good.

Hi, Alain!

It seems the fix lessened the impact of the leak, but did not solve it completely. I’ve upgraded our code base to 1.5.7, including the orthanc-databases plugins, and set about repeating the test. During this process I also included logs both when the plugin prepares a statement and when it deallocates it. I also crafted a small script to capture the process’ resident memory roughly every second.

The image below shows the result of this round of tests. Above you’ll find a graphic that was generated by the script. Below you’ll find a small assortment of terminals.

Screenshot from 2019-07-16 15-08-06.png

Clockwise, those terminals are:

  • Top left: the CSV generated by the script
  • Top right: the storescu terminal
  • Bottom: Orthanc’s logs grep’ed by Orthanc.PostgreSQLStatement, which basically shows that the statements are actually being deallocated

Hi Luiz,

From our experience, it seems that PostgreSQL increases RAM usage until it reaches half of the available RAM on the system.

HTH,

Hi, friends!

Just a quick update. Our custom Orthanc 1.5.7 was successfully deployed last Thursday and so far, the results are promissing. It seems the PostgreSQL process associated with Orthanc’s connection sits at around 145MB.

We are monitoring its memory consumption. If it stays like so next week given no restarts take place, we’ll consider the issue solved.

Thanks, Alain, for the solution. Thanks Benoît for your kind input. All have of imense help.

Best,
Luiz