RE: [BUG] Assert failure in ReorderBufferReturnTXN during logical decoding due to leaked specinsert change
Vishal Prasanna <vishal.g@zohocorp.com>
From: Vishal Prasanna <vishal.g@zohocorp.com>
To: "kurodahayato" <kuroda.hayato@fujitsu.com>
Cc: "pgsql-bugs" <pgsql-bugs@lists.postgresql.org>
Date: 2026-02-25T16:32:54Z
Lists: pgsql-bugs
Attachments
- PG14-17-Fix-specinsert-leak-in-ReorderBufferProcessTXN-error-path.patch (application/octet-stream)
Hi, Thanks for the response. > Anyway, I agreed that the leak could happen across all versions. > How about fixing the issue as shown below? Thought? > 1. Add an Assert() for PG16-. Yeah, Adding `Assert(txn->size == 0)` to PG 14, 15, 16 would ensure everything is cleaned up before freeing the `ReorderBufferTXN`. Consider adding this assert as well. > 2. Make sure specinsert is released for all supported versions. In PG 14 to 17, `ReorderBufferReturnChange()` is used to free the `ReorderBufferChange`. In PG 18, this function was renamed to `ReorderBufferFreeChange()`. Refer: PG 14, 15, 16, 17: PG14-17-Fix-specinsert-leak-in-ReorderBufferProcessTXN-error-path.patch PG 18: PG18-Fix-specinsert-leak-in-ReorderBufferProcessTXN-error-path.patch The above changes cover the `specinsert` cleanup in the error path for all supported versions. > 3. Consider a workload that could reproduce on PG18 and master. > 3-1. If found, the test code can be added for all versions. > 3-2. Otherwise, the test code can be added for PG17-. Found a workload that can reproduce the issue across all supported versions, except PG 14. For PG 14, since row_filter is not supported, so we can go with the 'publication does not exist' error instead. Refer: PG14-Test-specinsert-cleanup-in-ReorderBufferProcessTXN-error-path.patch For PG 15 - 18, using the row_filter option we can cause an error in the logical decoder. Refer: PG15-18-Test-specinsert-cleanup-in-ReorderBufferProcessTXN-error-path.patch >> Additional Suggestion: >> Currently in `PG_CATCH` block, `specinsert` is only freed in the `ERRCODE_TRANSACTION_ROLLBACK` branch >> for streaming or prepared transactions, via `ReorderBufferResetTXN()` at line 2691. >> Would it make sense to move the freeing of `specinsert` before the if/else branch, >> so that it is always freed regardless of the error path? This would avoid duplication and ensure >> that `specinsert` is always cleaned up. > It looks OK for me. In this case an argument should be reduced from > ReorderBufferResetTXN(), right? It is harmless because the function is a static one. Yes, the `specinsert` is no longer needed in `ReorderBufferResetTXN()`. Updated the patch where `specinsert` cleanup is now handled in the `PG_CATCH()` block of `ReorderBufferProcessTXN()`, so it is always freed before the if/else branch. Refer: PG14-17-Fix-specinsert-leak-in-ReorderBufferProcessTXN-error-path.patch PG18-Fix-specinsert-leak-in-ReorderBufferProcessTXN-error-path.patch Regards, Vishal Prasanna Zoho Corporation
Commits
-
logical decoding: Correctly free speculative insertion
- f50c329f538f 19 (unreleased) landed
- bd7b2184390f 18 (unreleased) landed
- ac445069002c 17 (unreleased) landed
- 813b0d8f455d 16 (unreleased) landed
- 1add4a41bc31 15 (unreleased) landed
- 0939aad56402 14 (unreleased) landed
-
Fix memory counter update in ReorderBuffer.
- dbed2e36625d 17.0 cited