Re: Simplify code building the LR conflict messages
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Álvaro Herrera <alvherre@kurilemu.de>
Cc: Peter Smith <smithpb2250@gmail.com>,
PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-11-29T18:21:00Z
Lists: 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 →
-
Improve errdetail for logical replication conflict messages.
- 48efefa6caac 19 (unreleased) landed
I wrote: > So I think this area desperately needs significant editorial > attention, as well as some fundamental rethinking of just what > information we should show. Perhaps using errcontext would help, > but I'm not sure. I think a large part of the problem stems from > trying to cram multiple error conditions into one ereport ... is it > possible to avoid that? After a little bit of thought, here's a sketch of a straw-man idea. 1. The longstanding output for unique constraint violations is like ERROR: duplicate key value violates unique constraint "foo_f1_f2_key" DETAIL: Key (f1, f2)=(1, 2) already exists. We could do worse than to use exactly that output (perhaps even sharing code) and add errcontext like CONTEXT: replicated INSERT of row with replica identity (f1, f2)=(1, 2) in table "foo" We should drop the full-row output for the reason I gave previously, and I do not see the value of the XID printout either. This would also serve (after s/INSERT/UPDATE/) for unique violations during replicated updates. 2. For no-matching-row in UPDATE or DELETE, perhaps ERROR: row to be updated[deleted] does not exist CONTEXT: replicated UPDATE[DELETE] of row with replica identity (f1, f2)=(1, 2) in table "foo" 3. I don't understand what delete_origin_differs means or why it's an error condition, so I won't dare to propose new text for that. But the new text should make the reason clear, and I think the same errcontext still works. 4. We need to make this a separate ereport for each problematic row. Without having looked at the code, I suspect the reason it works the way it does now is that the process will exit after ereport(ERROR). I don't want to completely redesign how ereport works, but maybe we could change replication apply so that the per-row reports are emitted as ereport(LOG), and then when we get to a place where we want to quit, end with ERROR: stopping replication because of previously-logged errors which would make the consequences clearer anyway. regards, tom lane