-
- Downloads
Prevent leakage of cached plans and execution trees in plpgsql DO blocks.
plpgsql likes to cache query plans and simple-expression execution state trees across calls. This is a considerable win for multiple executions of the same function. However, it's useless for DO blocks, since by definition those are executed only once and discarded. Nonetheless, we were allowing a DO block's expression execution trees to survive until end of transaction, resulting in a significant intra-transaction memory leak, as reported by Yeb Havinga. Worse, if the DO block exited with an error, the compiled form of the block's code was leaked till end of session --- along with subsidiary plancache entries. To fix, make DO blocks keep their expression execution trees in a private EState that's deleted at exit from the block, and add a PG_TRY block to plpgsql_inline_handler to make sure that memory cleanup happens even on error exits. Also add a regression test covering error handling in a DO block, because my first try at this broke that. (The test is not meant to prove that we don't leak memory anymore, though it could be used for that with a much larger loop count.) Ideally we'd back-patch this into all versions supporting DO blocks; but the patch needs to add a field to struct PLpgSQL_execstate, and that would break ABI compatibility for third-party plugins such as the plpgsql debugger. Given the small number of complaints so far, fixing this in HEAD only seems like an acceptable choice.
Showing
- src/pl/plpgsql/src/pl_exec.c 48 additions, 19 deletionssrc/pl/plpgsql/src/pl_exec.c
- src/pl/plpgsql/src/pl_handler.c 47 additions, 2 deletionssrc/pl/plpgsql/src/pl_handler.c
- src/pl/plpgsql/src/plpgsql.h 6 additions, 1 deletionsrc/pl/plpgsql/src/plpgsql.h
- src/test/regress/expected/plpgsql.out 29 additions, 0 deletionssrc/test/regress/expected/plpgsql.out
- src/test/regress/sql/plpgsql.sql 20 additions, 0 deletionssrc/test/regress/sql/plpgsql.sql
Loading
Please register or sign in to comment