| From: | Michael Paquier <michael(at)paquier(dot)xyz> |
|---|---|
| To: | Jacob Brazeal <jacob(dot)brazeal(at)gmail(dot)com> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Peter Geoghegan <pg(at)bowt(dot)ie>, Alvaro Herrera <alvherre(at)kurilemu(dot)de> |
| Subject: | Re: lost lock during toasting allows fk violation |
| Date: | 2026-07-29 04:00:25 |
| Message-ID: | aml62IuY_wUS5zvi@paquier.xyz |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Tue, Jul 28, 2026 at 05:44:15PM +0900, Michael Paquier wrote:
> Hmm. Couldn't one say that it is an ordering problem with the xmax
> computation in heap_update()?
>
> There is a window between the initial xmax computation and the TOAST
> and/or page extension work where we could have concurrent updates, due
> to the buffer lock getting released while we work on the TOAST data.
> Concurrent transactions are then free to manipulation states, and the
> xmax information gets overwritten in an incorrect way because it is
> only written *before* touching TOAST. We could recompute it after the
> TOAST/extension part is done, when the buffer lock is acquired again,
> I guess? This way we would be able to keep track of the FK locks that
> may have been added in-between.
>
> While looking at moving these blocks, I am not completely sure yet
> about the part with locker_remains and checked_lockers. I'd assume
> that we should recheck the xmax information with a
> xmax_infomask_changed() and a RawXmax(), or something like that..
Attached is an idea of the manipulations involved, reworking the
update flow as follows:
- Move the Xmax compulation to be after any TOAST work, set it to
InvalidTransactionId. The Cmin/Xmin is still done before.
- Release buffer lock.
- Do the TOAST work.
- Reacquire buffer lock.
- If we know that something has happened for TOAST and that the xmax
or t_infomask has changed, a concurrent locker has come around.
Assume that the locker is still active, switch locker_remains = true.
- Finish filling infomask[2] and the Xmax, like on HEAD, just later.
There is also an isolation test that detects the FK violation. This
code is tricky enough that way more than one pair of eyes should look
at this approach. So feel free to comment.
--
Michael
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Fix-loss-of-tuple-lock-during-TOAST-step-in-heap_upd.patch | text/plain | 11.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | shveta malik | 2026-07-29 04:10:11 | Re: Race between pg_dump and ALTER SEQUENCE can cause read failure |
| Previous Message | shveta malik | 2026-07-29 03:58:37 | Re: [PATCH] Preserve replication origin OIDs in pg_upgrade |