-
Notifications
You must be signed in to change notification settings - Fork 190
copy_data
memory bloat in v1.4
#473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We had a blocking flush in pg-1.3.x at every call to put_copy_data. This made sure, that all data is sent until the next put_copy_data. In ged#462 (and pg-1.4.0 to .2) the behaviour was changed to rely on the non-blocking flushs libpq is doing internally. This makes a decent performance improvement especially on Windows. Unfortunately ged#473 proved that memory bloat can happen, when sending the data is slower than calls to put_copy_data happen. As a trade-off this proposes to do a blocking flush only every 100 calls. If libpq is running in blocking mode (PG::Connection.async_api = false) put_copy_data does a blocking flush every time new memory is allocated. Unfortunately we don't have this kind of information, since we don't have access to libpq's PGconn struct and the return codes don't give us an indication when this happens. So doing a flush at every fixed number of calls is a very simple heuristic. Fixes ged#473
I can reproduce this issue. Not that dramatic as you measured, but also measurable. The root cause is #462. I made it when I noticed that My proposal is to fix it like #474. Not ideal, but I think the only practical trade-off we can do. CC @SamSaffron |
Thanks for the quick fix @larskanis - #474 does indeed fix the issue in my minimal repro script ❤️
Aha I see! Indeed, adding a |
copy_data
memory leak in v1.4copy_data
memory bloat in v1.4
We had a blocking flush in pg-1.3.x at every call to put_copy_data. This made sure, that all data is sent until the next put_copy_data. In ged#462 (and pg-1.4.0 to .2) the behaviour was changed to rely on the non-blocking flushs libpq is doing internally. This makes a decent performance improvement especially on Windows. Unfortunately ged#473 proved that memory bloat can happen, when sending the data is slower than calls to put_copy_data happen. As a trade-off this proposes to do a blocking flush only every 100 calls. If libpq is running in blocking mode (PG::Connection.async_api = false) put_copy_data does a blocking flush every time new memory is allocated. Unfortunately we don't have this kind of information, since we don't have access to libpq's PGconn struct and the return codes don't give us an indication when this happens. So doing a flush at every fixed number of calls is a very simple heuristic. Fixes ged#473
We use
Connection#copy_data
to stream large volumes of data into a temporary table. We recently observed significant performance degradation and increased memory use for this system. Here's a minimal reproduction:With version
1.3.5
, this script takes ~10s on my machine, and reports ~47mb RSS at the end. With version1.4.0
(and1.4.1
,1.4.2
), it takes ~80s and reports ~182mb RSS at the end. The RSS appears to scale with the amount of data being copied.The text was updated successfully, but these errors were encountered: