Fix memory leaks when freeing WAL readers

Commit 3f1ce97346 introduced a circular buffer for decoded WAL records,
with separate allocations for records that do not fit in the buffer.
However, XLogReaderFree() did not release separately allocated
records remaining in the decode queue. In particular, the last record
returned by XLogReadRecord() remains queued until released, so freeing
the reader could leak that record.

For many callers, the leaked memory is reclaimed when the containing
memory context is reset or deleted. However, it can accumulate in
long-lived contexts. For example, when checkpointing prepared
transactions, XlogReadTwoPhaseData() creates a WAL reader, reads the
PREPARE record, and frees the reader. Large PREPARE records can
therefore leave allocations in checkpointer_context, which is not
reset during normal operation. These allocations accumulate until
an error resets the context or the checkpointer exits.

Fix this by calling ResetDecoder() in XLogReaderFree() to release all
separately allocated records in the queue. Do this before freeing the
decode buffer, since the queue can also contain records stored in that
buffer.

Backpatch to v15, where the circular WAL decoding buffer was
introduced.

Author: Tomás Senart <[email protected]>
Reviewed-by: Fujii Masao <[email protected]>
Discussion: 
https://postgr.es/m/caeeba3uai8tgpd6p5sx_fzbu3khmwsvu9wuqa8jpspq1rjr...@mail.gmail.com
Backpatch-through: 15

Branch
------
REL_16_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/4c271dc216065c8e6c99ba3097e831e6ef6cd9e1

Modified Files
--------------
src/backend/access/transam/xlogreader.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

Reply via email to