Re: BUG #19896: transaction_timeout misbehaves after ROLLBACK TO SAVEPOINT and after errors

From: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
To: nickevanoorschot(at)gmail(dot)com, PostgreSQL mailing lists <pgsql-bugs(at)lists(dot)postgresql(dot)org>
Subject: Re: BUG #19896: transaction_timeout misbehaves after ROLLBACK TO SAVEPOINT and after errors
Date: 2026-11-13 09:33:46
Message-ID: 87676E9A-DCA9-46AE-9214-5C374D5832F3@yandex-team.ru
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Nicke,

Thank you for the report. Yes, this looks like a bug.

I'm attaching draft fixes for cases 1 and 2. GUC restoration runs after
the subtransaction enters TRANS_ABORT, so IsTransactionState() prevented
the assign hook from updating the timer. Separately, PostgresMain
cancelled the surviving transaction's timer on ERROR. The draft
preserves its original deadline rather than restarting the timeout.

For case 3, I had already noted missing coverage for terminating a
session in "idle in transaction (aborted)" [0]. AbortTransaction()
currently stops the timer and rolls back SET LOCAL. These drafts still
leave that lifetime issue unresolved.

The last patch is particularly tentative. With transaction_timeout = 2s
and idle_in_transaction_session_timeout = 3s, both set at session level,
a full abort leaves neither timer running. Here time is measured from
BEGIN, with an error at t=1s and no further commands:

t=0s t=1s t=2s t=4s
|-----------|-----------|-----------------------|
BEGIN ERROR transaction deadline idle deadline
full abort FATAL if kept active FATAL with 0004

The patch would terminate the session at t=4s: the 3s idle wait starts
after the error at t=1s. Keeping the transaction timer effective would
terminate it at the original t=2s deadline.
We had deliberately suppressed longer or equal timeouts [1]. Should a
fully aborted transaction block be covered by transaction_timeout,
idle_in_transaction_session_timeout, or neither? I lean slightly
towards keeping transaction_timeout effective until the transaction
block ends, including while it is aborted.

First patch with test is for an exploration, maybe some of it will be
useful in future.

Feedback is welcome. I'll keep thinking about this.

Thank you!

Best regards, Andrey Borodin.

[0] https://postgr.es/m/4C30F833-C0F2-4664-B0FF-192FD8AB2E2E%40yandex-team.ru
[1] https://postgr.es/m/A8009945-7FB7-4E75-9239-CCC351F8050C%40yandex-team.ru

Attachment Content-Type Size
v1-0001-Add-coverage-for-transaction-timeout-cleanup.patch application/octet-stream 8.0 KB
v1-0002-Fix-transaction-timeout-cleanup-during-GUC-restor.patch application/octet-stream 3.4 KB
v1-0003-Preserve-transaction-timeout-across-recoverable-e.patch application/octet-stream 3.3 KB
v1-0004-Do-not-suppress-idle-timeout-for-an-inactive-tran.patch application/octet-stream 2.1 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message shveta malik 2026-11-13 10:10:08 Re: BUG #19864: pg_get_publication_tables() gets cache lookup error after concurrent DROP PUBLICATION
Previous Message Zsolt Parragi 2026-11-13 09:31:17 Re: BUG #19864: pg_get_publication_tables() gets cache lookup error after concurrent DROP PUBLICATION