Re: BUG #18815: Logical replication worker Segmentation fault
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@lists.postgresql.org
Cc: Sergey Belyashov <sergey.belyashov@gmail.com>,
Tomas Vondra <tomas@vondra.me>
Date: 2025-02-18T20:38:34Z
Lists: pgsql-bugs, pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix uninitialized index information access during apply.
- 12eece5fd54c 18.0 landed
-
Assert that ExecOpenIndices and ExecCloseIndices are not repeated.
- e596e077bbb3 18.0 landed
-
Fix crash in brininsertcleanup during logical replication.
- 9ff68679b50f 18.0 landed
- 788baa9a25ae 17.5 landed
Attachments
- v1-0001-Demonstrate-crash-in-brininsertcleanup-during-log.patch (text/x-diff) patch v1-0001
- v1-0002-Harden-brininsertcleanup-against-repeat-calls.patch (text/x-diff) patch v1-0002
- v1-0003-Assert-that-ExecOpenIndices-and-ExecCloseIndices-.patch (text/x-diff) patch v1-0003
- v1-0004-Avoid-duplicate-ExecOpenIndices-ExecCloseIndices-.patch (text/x-diff) patch v1-0004
[ redirecting to -hackers for patch discussion ] Here's a completed set of patches for bug #18815 [1] (which, briefly, is that the logrep worker opens/closes indexes multiple times and thereby breaks brininsertcleanup). 0001 adds a subscriber-side BRIN index to 013_partition.pl, which replicates the crash Sergey reported. I've got mixed feelings about whether to actually commit this: it's certainly useful for testing this fix, but without context it looks like a pretty random thing to do. It could be justified perhaps on the grounds of testing aminsertcleanup callbacks within replication, since BRIN is the only core index type that has such a callback. 0002 fixes the crash by hardening brininsertcleanup against multiple calls. I think that this is patching a symptom not the root cause, but it still seems like good defensive programming. 0003 adds Asserts to ExecOpenIndices and ExecCloseIndices to check that they're not called more than once per ResultRelInfo, and thereby exposes what I consider the root cause: apply_handle_tuple_routing opens the indexes twice and then closes them twice. This somewhat accidentally leaves us with zero refcounts and zero locks on the indexes, so in the absence of aminsertcleanup callbacks the only real reason to complain is the duplicative construction of the IndexInfo structures. But the double call of brininsertcleanup breaks the existing coding of that function, and it might well break third-party aminsertcleanup callbacks if there are any. So I think we should institute a policy that this coding pattern is forbidden. And finally, 0004 fixes worker.c to not do that. This turned out simpler than I thought, because I was misled by believing that the ExecOpenIndices/ExecCloseIndices calls in apply_handle_tuple_routing itself do something useful. They don't, and should be nuked outright. I don't intend 0003 for back-patch, but the rest of this has to go back as far as the bug can be observed, which I didn't test yet. To be clear, 0004 would fix the issue even without 0002, but I still think we should back-patch both. regards, tom lane [1] https://www.postgresql.org/message-id/flat/18815-2a0407cc7f40b327%40postgresql.org