Assertion failure during initdb with transaction_timeout set

Started by Fujii Masao6 months ago3 messages
#1Fujii Masao
masao.fujii@oss.nttdata.com

Hi,

While discussing the assertion failure with track_commit_timestamp=on during initdb [1]/messages/by-id/87plejmnpy.fsf@163.com,
I found a similar issue with another GUC: transaction_timeout.

Running initdb -c transaction_timeout=1 triggers the following assertion failure:

running bootstrap script ... TRAP: failed Assert("all_timeouts_initialized"), File: "timeout.c", Line: 164, PID: 22057
0 postgres 0x00000001105d9d02 ExceptionalCondition + 178
1 postgres 0x0000000110612af7 enable_timeout + 55
2 postgres 0x0000000110612aa9 enable_timeout_after + 73
3 postgres 0x000000010fead8e0 StartTransaction + 816
4 postgres 0x000000010fead4a1 StartTransactionCommand + 65
5 postgres 0x000000010fef01de BootstrapModeMain + 1518
6 postgres 0x0000000110167ef4 main + 676
7 dyld 0x00007ff805092530 start + 3056
child process was terminated by signal 6: Abort trap: 6

This happens because enable_timeout() tries to start the transaction timeout
before InitializeTimeouts() has been called, i.e., the timeout subsystem
hasn't been initialized yet.

To address this, I'm thinking forcibly setting transaction_timeout to 0
during bootstrap or in initdb.

Any thoughts?

Regards,

[1]: /messages/by-id/87plejmnpy.fsf@163.com

--
Fujii Masao
NTT DATA Japan Corporation

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fujii Masao (#1)
Re: Assertion failure during initdb with transaction_timeout set

Fujii Masao <masao.fujii@oss.nttdata.com> writes:

While discussing the assertion failure with track_commit_timestamp=on during initdb [1],
I found a similar issue with another GUC: transaction_timeout.

This happens because enable_timeout() tries to start the transaction timeout
before InitializeTimeouts() has been called, i.e., the timeout subsystem
hasn't been initialized yet.

To address this, I'm thinking forcibly setting transaction_timeout to 0
during bootstrap or in initdb.

I don't like inventing a different workaround for each case we find.
The precedent established by the other patch is to prevent the
relevant subsystem from starting if IsBootstrapProcessingMode().
Can't we do something similar here?

regards, tom lane

#3Fujii Masao
masao.fujii@oss.nttdata.com
In reply to: Tom Lane (#2)
Re: Assertion failure during initdb with transaction_timeout set

On 2025/07/04 23:47, Tom Lane wrote:

Fujii Masao <masao.fujii@oss.nttdata.com> writes:

While discussing the assertion failure with track_commit_timestamp=on during initdb [1],
I found a similar issue with another GUC: transaction_timeout.

This happens because enable_timeout() tries to start the transaction timeout
before InitializeTimeouts() has been called, i.e., the timeout subsystem
hasn't been initialized yet.

To address this, I'm thinking forcibly setting transaction_timeout to 0
during bootstrap or in initdb.

I don't like inventing a different workaround for each case we find.
The precedent established by the other patch is to prevent the
relevant subsystem from starting if IsBootstrapProcessingMode().
Can't we do something similar here?

One idea is to allow the enable_timeout_xxx() functions to be called before
the timeout mechanism is initialized, similar to how reschedule_timeouts()
handles it. However, this might make it harder to catch bugs where timeouts
are enabled too early in cases where that shouldn't be allowed.

void
reschedule_timeouts(void)
{
/* For flexibility, allow this to be called before we're initialized. */
if (!all_timeouts_initialized)
return;

Another idea is to have the enable_timeout_xxx() functions simply return
immediately when IsBootstrapProcessingMode() is true.

That said, either approach involves adding checks to functions that may be
called frequently, which some might prefer to avoid for performance reasons.

Regards,

--
Fujii Masao
NTT DATA Japan Corporation