Skip to content

PG-2229 Memory leaks once query executed via SPI interface#634

Open
artemgavrilov wants to merge 2 commits intomainfrom
PG-2229-spi-memory-leak
Open

PG-2229 Memory leaks once query executed via SPI interface#634
artemgavrilov wants to merge 2 commits intomainfrom
PG-2229-spi-memory-leak

Conversation

@artemgavrilov
Copy link
Copy Markdown
Contributor

@artemgavrilov artemgavrilov commented Mar 19, 2026

PG-2229

Description

Before attached our memory context cleanup callback to MessageContext, however this context doesn't exist when query executed via SPI. That caused memory leak. In this PR we explicitly reset our context when we no longer need its data, as there is no other context that matches our lifetime requirements.

How to test

I used worker_spi extension from postgres/src/test/modules/worker_spi

  1. Start postgresql with PGSM added to preload libs
  2. CREATE EXTENSION worker_spi;
  3. SELECT worker_spi_launch(1) IS NOT NULL;
  4. SELECT pid, query FROM pg_stat_activity; find PID of the process that executes query WITH deleted AS (DELETE FROM...
  5. SELECT pg_log_backend_memory_contexts(<PID>);
  6. Check postgres logs for such record LOG: level: 2; pg_stat_monitor local store: 8192 total in 1 blocks; 7952 free (0 chunks); 240 used.

Without this patch used space will constantly grow over time, while with the patch it will stay constant.

Links

@artemgavrilov artemgavrilov changed the title Pg 2229 spi memory leak PG-2229 Memory leak once query executed via SPI interface Mar 19, 2026
@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch from 59caea0 to 1fd47f9 Compare March 19, 2026 17:10
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 88.46154% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.08%. Comparing base (b6ffd37) to head (34aa683).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
pg_stat_monitor.c 88.46% 3 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #634      +/-   ##
==========================================
+ Coverage   85.89%   86.08%   +0.18%     
==========================================
  Files           3        3              
  Lines        1354     1358       +4     
  Branches      218      219       +1     
==========================================
+ Hits         1163     1169       +6     
+ Misses         91       90       -1     
+ Partials      100       99       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch 5 times, most recently from 189046f to 1f47fbc Compare March 20, 2026 15:24
if (nesting_level == 0)
#else
if ((nesting_level + plan_nested_level) == 0)
#endif
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we have to use try/finally because our context created under TopMemoryContext, so it lives forever. In this hook we may have an exception and we want to cleanup memory in this case too.

@artemgavrilov artemgavrilov marked this pull request as ready for review March 20, 2026 16:46
@artemgavrilov artemgavrilov changed the title PG-2229 Memory leak once query executed via SPI interface PG-2229 Memory leaks once query executed via SPI interface Mar 20, 2026
@artemgavrilov
Copy link
Copy Markdown
Contributor Author

BTW probably safer option will be to create our memory context under TopTransactionContext and recreate it each time. Not sure that it will cause dramatic perfomance penalty.

@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch from 1f47fbc to bd420f9 Compare March 25, 2026 12:34
@artemgavrilov
Copy link
Copy Markdown
Contributor Author

Something went wrong after sync with main branch, I'm on it.

@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch 3 times, most recently from a7f6a00 to dab4d33 Compare March 25, 2026 16:25
Comment on lines +1029 to +1033
#if PG_VERSION_NUM < 160000
PG_TRY();
#else
PG_TRY(1);
#endif
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is ugly.

Comment on lines +1047 to +1057
nesting_level--;
}
#if PG_VERSION_NUM < 160000
PG_CATCH();
#else
PG_CATCH(1);
#endif
{
nesting_level--;
PG_RE_THROW();
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this can be replaced with PG_FINALLY since we dropped PG12 support. Will do it in the following PG.

@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch from dab4d33 to b089d3e Compare March 25, 2026 16:34
Attaching memory reset callback to MessageContext is wrong as for
background workers that use SPI for query execution such context doesn't
exist. There is no other context which lifetime matches our needs, so
instead reset our memory context explicitly when we no longer need its
data.
As we delete entry from the list we should also free its memory, even if
we later reset whole memory context.
@artemgavrilov artemgavrilov force-pushed the PG-2229-spi-memory-leak branch from b089d3e to 34aa683 Compare March 25, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant